1   /*                        __    __  __  __    __  ___
2    *                       \  \  /  /    \  \  /  /  __/
3    *                        \  \/  /  /\  \  \/  /  /
4    *                         \____/__/  \__\____/__/.ɪᴏ
5    * ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ
6    */
7   package io.vavr.collection;
8   
9   import io.vavr.Tuple;
10  import io.vavr.AbstractValueTest;
11  import io.vavr.PartialFunction;
12  import io.vavr.Tuple2;
13  import io.vavr.control.Option;
14  import org.junit.Test;
15  
16  import java.io.*;
17  import java.math.BigDecimal;
18  import java.math.BigInteger;
19  import java.util.*;
20  import java.util.function.Function;
21  import java.util.function.Supplier;
22  import java.util.stream.Collector;
23  
24  import static java.lang.System.lineSeparator;
25  import static java.util.Arrays.asList;
26  import static java.util.Comparator.comparingInt;
27  import static org.assertj.core.api.Assertions.assertThatThrownBy;
28  import static org.assertj.core.api.Assertions.fail;
29  import static org.assertj.core.api.Assertions.within;
30  
31  public abstract class AbstractTraversableTest extends AbstractValueTest {
32  
33      protected final boolean isTraversableAgain() {
34          return empty().isTraversableAgain();
35      }
36  
37      protected abstract <T> Collector<T, ArrayList<T>, ? extends Traversable<T>> collector();
38  
39      @Override
40      protected abstract <T> Traversable<T> empty();
41  
42      protected boolean emptyShouldBeSingleton() {
43          return true;
44      }
45  
46      @Override
47      protected abstract <T> Traversable<T> of(T element);
48  
49      @SuppressWarnings("unchecked")
50      @Override
51      protected abstract <T> Traversable<T> of(T... elements);
52  
53      protected abstract <T> Traversable<T> ofAll(Iterable<? extends T> elements);
54  
55      protected abstract <T extends Comparable<? super T>> Traversable<T> ofJavaStream(java.util.stream.Stream<? extends T> javaStream);
56  
57      protected abstract Traversable<Boolean> ofAll(boolean... elements);
58  
59      protected abstract Traversable<Byte> ofAll(byte... elements);
60  
61      protected abstract Traversable<Character> ofAll(char... elements);
62  
63      protected abstract Traversable<Double> ofAll(double... elements);
64  
65      protected abstract Traversable<Float> ofAll(float... elements);
66  
67      protected abstract Traversable<Integer> ofAll(int... elements);
68  
69      protected abstract Traversable<Long> ofAll(long... elements);
70  
71      protected abstract Traversable<Short> ofAll(short... elements);
72  
73      protected abstract <T> Traversable<T> tabulate(int n, Function<? super Integer, ? extends T> f);
74  
75      protected abstract <T> Traversable<T> fill(int n, Supplier<? extends T> s);
76  
77      // -- static empty()
78  
79      @Test
80      public void shouldCreateNil() {
81          final Traversable<?> actual = empty();
82          assertThat(actual.length()).isEqualTo(0);
83      }
84  
85      // -- static narrow()
86  
87      @Test
88      public void shouldNarrowTraversable() {
89          final Traversable<Double> doubles = of(1.0d);
90          final Traversable<Number> numbers = Traversable.narrow(doubles);
91          final boolean actual = numbers.contains(new BigDecimal("2.0"));
92          assertThat(actual).isFalse();
93      }
94  
95      // -- static of()
96  
97      @Test
98      public void shouldCreateSeqOfSeqUsingCons() {
99          final List<List<Object>> actual = of(List.empty()).toList();
100         assertThat(actual).isEqualTo(List.of(List.empty()));
101     }
102 
103     // -- static of(T...)
104 
105     @Test
106     public void shouldCreateInstanceOfElements() {
107         final List<Integer> actual = of(1, 2).toList();
108         assertThat(actual).isEqualTo(List.of(1, 2));
109     }
110 
111     // -- static of(Iterable)
112 
113     @Test
114     public void shouldCreateListOfIterable() {
115         final java.util.List<Integer> arrayList = asList(1, 2);
116         final List<Integer> actual = ofAll(arrayList).toList();
117         assertThat(actual).isEqualTo(List.of(1, 2));
118     }
119 
120     // -- static ofAll(java.util.stream.Stream)
121 
122     @Test
123     public void shouldCreateStreamFromEmptyJavaUtilStream() {
124         final java.util.stream.Stream<Integer> javaStream = java.util.stream.Stream.empty();
125         assertThat(ofJavaStream(javaStream)).isEqualTo(empty());
126     }
127 
128     @Test
129     public void shouldCreateStreamFromNonEmptyJavaUtilStream() {
130         final java.util.stream.Stream<Integer> javaStream = java.util.stream.Stream.of(1, 2, 3);
131         assertThat(ofJavaStream(javaStream)).isEqualTo(of(1, 2, 3));
132     }
133 
134     // -- static of(<primitive array>)
135 
136     @Test
137     public void shouldCreateListOfPrimitiveBooleanArray() {
138         final Traversable<Boolean> actual = ofAll(true, false);
139         final Traversable<Boolean> expected = of(true, false);
140         assertThat(actual).isEqualTo(expected);
141     }
142 
143     @Test
144     public void shouldCreateListOfPrimitiveByteArray() {
145         final Traversable<Byte> actual = ofAll((byte) 1, (byte) 2, (byte) 3);
146         final Traversable<Byte> expected = of((byte) 1, (byte) 2, (byte) 3);
147         assertThat(actual).isEqualTo(expected);
148     }
149 
150     @Test
151     public void shouldCreateListOfPrimitiveCharArray() {
152         final Traversable<Character> actual = ofAll('a', 'b', 'c');
153         final Traversable<Character> expected = of('a', 'b', 'c');
154         assertThat(actual).isEqualTo(expected);
155     }
156 
157     @Test
158     public void shouldCreateListOfPrimitiveDoubleArray() {
159         final Traversable<Double> actual = ofAll(1d, 2d, 3d);
160         final Traversable<Double> expected = of(1d, 2d, 3d);
161         assertThat(actual).isEqualTo(expected);
162     }
163 
164     @Test
165     public void shouldCreateListOfPrimitiveFloatArray() {
166         final Traversable<Float> actual = ofAll(1f, 2f, 3f);
167         final Traversable<Float> expected = of(1f, 2f, 3f);
168         assertThat(actual).isEqualTo(expected);
169     }
170 
171     @Test
172     public void shouldCreateListOfPrimitiveIntArray() {
173         final Traversable<Integer> actual = ofAll(1, 2, 3);
174         final Traversable<Integer> expected = of(1, 2, 3);
175         assertThat(actual).isEqualTo(expected);
176     }
177 
178     @Test
179     public void shouldCreateListOfPrimitiveLongArray() {
180         final Traversable<Long> actual = ofAll(1L, 2L, 3L);
181         final Traversable<Long> expected = of(1L, 2L, 3L);
182         assertThat(actual).isEqualTo(expected);
183     }
184 
185     @Test
186     public void shouldCreateListOfPrimitiveShortArray() {
187         final Traversable<Short> actual = ofAll((short) 1, (short) 2, (short) 3);
188         final Traversable<Short> expected = of((short) 1, (short) 2, (short) 3);
189         assertThat(actual).isEqualTo(expected);
190     }
191 
192     // -- average
193 
194     @Test
195     public void shouldReturnNoneWhenComputingAverageOfNil() {
196         assertThat(empty().average()).isEqualTo(Option.none());
197     }
198 
199     @Test(expected = UnsupportedOperationException.class)
200     public void shouldThrowWhenComputingAverageOfStrings() {
201         of("1", "2", "3").average();
202     }
203 
204     @Test
205     public void shouldComputeAverageOfByte() {
206         assertThat(of((byte) 1, (byte) 2).average().get()).isEqualTo(1.5);
207     }
208 
209     @Test
210     public void shouldComputeAverageOfDouble() {
211         assertThat(of(.1, .2, .3).average().get()).isEqualTo(.2, within(10e-17));
212     }
213 
214     @Test
215     public void shouldComputeAverageOfFloat() {
216         assertThat(of(.1f, .2f, .3f).average().get()).isEqualTo(.2, within(10e-9));
217     }
218 
219     @Test
220     public void shouldComputeAverageOfInt() {
221         assertThat(of(1, 2, 3).average().get()).isEqualTo(2);
222     }
223 
224     @Test
225     public void shouldComputeAverageOfLong() {
226         assertThat(of(1L, 2L, 3L).average().get()).isEqualTo(2);
227     }
228 
229     @Test
230     public void shouldComputeAverageOfShort() {
231         assertThat(of((short) 1, (short) 2, (short) 3).average().get()).isEqualTo(2);
232     }
233 
234     @Test
235     public void shouldComputeAverageOfBigInteger() {
236         assertThat(of(BigInteger.ZERO, BigInteger.ONE).average().get()).isEqualTo(.5);
237     }
238 
239     @Test
240     public void shouldComputeAverageOfBigDecimal() {
241         assertThat(of(BigDecimal.ZERO, BigDecimal.ONE).average().get()).isEqualTo(.5);
242     }
243 
244     // -- collect
245 
246     @Test
247     public void shouldThrowOnCollectWhenPartialFunctionIsNull() {
248         assertThatThrownBy(() -> empty().collect((PartialFunction<Object, ?>) null))
249                 .isExactlyInstanceOf(NullPointerException.class)
250                 .hasMessage("partialFunction is null");
251     }
252 
253     @Test
254     public void shouldCollectUsingPartialFunction() {
255         final PartialFunction<Integer, String> pf = new PartialFunction<Integer, String>() {
256             @Override
257             public String apply(Integer i) {
258                 return String.valueOf(i);
259             }
260             @Override
261             public boolean isDefinedAt(Integer i) {
262                 return i % 2 == 1;
263             }
264         };
265         final Traversable<String> actual = of(1, 2, 3).collect(pf);
266         assertThat(actual).isEqualTo(of("1", "3"));
267     }
268 
269     // -- contains
270 
271     @Test
272     public void shouldRecognizeNilContainsNoElement() {
273         final boolean actual = empty().contains(null);
274         assertThat(actual).isFalse();
275     }
276 
277     @Test
278     public void shouldRecognizeNonNilDoesNotContainElement() {
279         final boolean actual = of(1, 2, 3).contains(0);
280         assertThat(actual).isFalse();
281     }
282 
283     @Test
284     public void shouldRecognizeNonNilDoesContainElement() {
285         final boolean actual = of(1, 2, 3).contains(2);
286         assertThat(actual).isTrue();
287     }
288 
289     // -- containsAll
290 
291     @Test
292     public void shouldHandleDuplicates() {
293         final boolean actual = of(1, 2, 3, 2, 3, 1).containsAll(of(1, 2, 2));
294         assertThat(actual).isTrue();
295     }
296 
297     @Test
298     public void shouldRecognizeNilNotContainsAllElements() {
299         final boolean actual = empty().containsAll(of(1, 2, 3));
300         assertThat(actual).isFalse();
301     }
302 
303     @Test
304     public void shouldRecognizeNonNilNotContainsAllOverlappingElements() {
305         final boolean actual = of(1, 2, 3).containsAll(of(2, 3, 4));
306         assertThat(actual).isFalse();
307     }
308 
309     @Test
310     public void shouldRecognizeNonNilContainsAllOnSelf() {
311         final boolean actual = of(1, 2, 3).containsAll(of(1, 2, 3));
312         assertThat(actual).isTrue();
313     }
314 
315     // -- count
316 
317     @Test
318     public void shouldCountWhenIsEmpty() {
319         assertThat(empty().count(ignored -> true)).isEqualTo(0);
320     }
321 
322     @Test
323     public void shouldCountWhenNoneSatisfiesThePredicate() {
324         assertThat(of(1, 2, 3).count(ignored -> false)).isEqualTo(0);
325     }
326 
327     @Test
328     public void shouldCountWhenAllSatisfyThePredicate() {
329         assertThat(of(1, 2, 3).count(ignored -> true)).isEqualTo(3);
330     }
331 
332     @Test
333     public void shouldCountWhenSomeSatisfyThePredicate() {
334         assertThat(of(1, 2, 3).count(i -> i % 2 == 0)).isEqualTo(1);
335     }
336 
337     // -- distinct
338 
339     @Test
340     public void shouldComputeDistinctOfEmptyTraversable() {
341         if (useIsEqualToInsteadOfIsSameAs()) {
342             assertThat(empty().distinct()).isEqualTo(empty());
343         } else {
344             assertThat(empty().distinct()).isSameAs(empty());
345         }
346     }
347 
348     @Test
349     public void shouldComputeDistinctOfNonEmptyTraversable() {
350         final Traversable<Integer> testee = of(1, 1, 2, 2, 3, 3);
351         final Traversable<Integer> actual = testee.distinct();
352         final Traversable<Integer> expected = of(1, 2, 3);
353         assertThat(actual).isEqualTo(expected);
354         if (testee.isDistinct()) {
355             assertThat(actual).isSameAs(testee);
356         }
357     }
358 
359     // -- distinctBy(Comparator)
360 
361     @Test
362     public void shouldComputeDistinctByOfEmptyTraversableUsingComparator() {
363         final Comparator<Integer> comparator = comparingInt(i -> i);
364         if (useIsEqualToInsteadOfIsSameAs()) {
365             assertThat(this.<Integer> empty().distinctBy(comparator)).isEqualTo(empty());
366         } else {
367             assertThat(this.<Integer> empty().distinctBy(comparator)).isSameAs(empty());
368         }
369     }
370 
371     @Test
372     public void shouldComputeDistinctByOfNonEmptyTraversableUsingComparator() {
373         final Comparator<String> comparator = comparingInt(s -> (s.charAt(1)));
374         final Traversable<String> distinct = of("1a", "2a", "3a", "3b", "4b", "5c").distinctBy(comparator).map(s -> s.substring(1));
375         assertThat(distinct).isEqualTo(of("a", "b", "c"));
376     }
377 
378 
379     @Test
380     public void shouldReturnSameInstanceWhenDistinctByComparatorEmptyTraversable() {
381         final Traversable<?> empty = empty();
382         assertThat(empty.distinctBy(Comparators.naturalComparator())).isSameAs(empty);
383     }
384 
385     // -- distinctBy(Function)
386 
387     @Test
388     public void shouldComputeDistinctByOfEmptyTraversableUsingKeyExtractor() {
389         if (useIsEqualToInsteadOfIsSameAs()) {
390             assertThat(empty().distinctBy(Function.identity())).isEqualTo(empty());
391         } else {
392             assertThat(empty().distinctBy(Function.identity())).isSameAs(empty());
393         }
394     }
395 
396     @Test
397     public void shouldComputeDistinctByOfNonEmptyTraversableUsingKeyExtractor() {
398         final Function<String, Character> function = c -> c.charAt(1);
399         final Traversable<String> distinct = of("1a", "2a", "3a", "3b", "4b", "5c").distinctBy(function).map(s -> s.substring(1));
400         assertThat(distinct).isEqualTo(of("a", "b", "c"));
401     }
402 
403     @Test
404     public void shouldReturnSameInstanceWhenDistinctByFunctionEmptyTraversable() {
405         final Traversable<?> empty = empty();
406         assertThat(empty.distinctBy(Function.identity())).isSameAs(empty);
407     }
408 
409     // -- drop
410 
411     @Test
412     public void shouldDropNoneOnNil() {
413         if (useIsEqualToInsteadOfIsSameAs()) {
414             assertThat(empty().drop(1)).isEqualTo(empty());
415         } else {
416             assertThat(empty().drop(1)).isSameAs(empty());
417         }
418     }
419 
420     @Test
421     public void shouldDropNoneIfCountIsNegative() {
422         assertThat(of(1, 2, 3).drop(-1)).isEqualTo(of(1, 2, 3));
423     }
424 
425     @Test
426     public void shouldDropAsExpectedIfCountIsLessThanSize() {
427         assertThat(of(1, 2, 3).drop(2)).isEqualTo(of(3));
428     }
429 
430     @Test
431     public void shouldDropAllIfCountExceedsSize() {
432         if (useIsEqualToInsteadOfIsSameAs()) {
433             assertThat(of(1, 2, 3).drop(4)).isEqualTo(empty());
434         } else {
435             assertThat(of(1, 2, 3).drop(4)).isSameAs(empty());
436         }
437     }
438 
439     @Test
440     public void shouldReturnSameInstanceWhenDropZeroCount() {
441         final Traversable<Integer> t = of(1, 2, 3);
442         assertThat(t.drop(0)).isSameAs(t);
443     }
444 
445     @Test
446     public void shouldReturnSameInstanceWhenDropNegativeCount() {
447         final Traversable<Integer> t = of(1, 2, 3);
448         assertThat(t.drop(-1)).isSameAs(t);
449     }
450 
451     @Test
452     public void shouldReturnSameInstanceWhenEmptyDropOne() {
453         final Traversable<?> empty = empty();
454         assertThat(empty.drop(1)).isSameAs(empty);
455     }
456 
457     // -- dropRight
458 
459     @Test
460     public void shouldDropRightNoneOnNil() {
461         if (useIsEqualToInsteadOfIsSameAs()) {
462             assertThat(empty().dropRight(1)).isEqualTo(empty());
463         } else {
464             assertThat(empty().dropRight(1)).isSameAs(empty());
465         }
466     }
467 
468     @Test
469     public void shouldDropRightNoneIfCountIsNegative() {
470         assertThat(of(1, 2, 3).dropRight(-1)).isEqualTo(of(1, 2, 3));
471     }
472 
473     @Test
474     public void shouldDropRightAsExpectedIfCountIsLessThanSize() {
475         assertThat(of(1, 2, 3).dropRight(2)).isEqualTo(of(1));
476     }
477 
478     @Test
479     public void shouldDropRightAllIfCountExceedsSize() {
480         if (useIsEqualToInsteadOfIsSameAs()) {
481             assertThat(of(1, 2, 3).dropRight(4)).isEqualTo(empty());
482         } else {
483             assertThat(of(1, 2, 3).dropRight(4)).isSameAs(empty());
484         }
485     }
486 
487     @Test
488     public void shouldReturnSameInstanceWhenDropRightZeroCount() {
489         final Traversable<Integer> t = of(1, 2, 3);
490         assertThat(t.dropRight(0)).isSameAs(t);
491     }
492 
493     @Test
494     public void shouldReturnSameInstanceWhenDropRightNegativeCount() {
495         final Traversable<Integer> t = of(1, 2, 3);
496         assertThat(t.dropRight(-1)).isSameAs(t);
497     }
498 
499     @Test
500     public void shouldReturnSameInstanceWhenEmptyDropRightOne() {
501         final Traversable<?> empty = empty();
502         assertThat(empty.dropRight(1)).isSameAs(empty);
503     }
504 
505     // -- dropUntil
506 
507     @Test
508     public void shouldDropUntilNoneOnNil() {
509         if (useIsEqualToInsteadOfIsSameAs()) {
510             assertThat(empty().dropUntil(ignored -> true)).isEqualTo(empty());
511         } else {
512             assertThat(empty().dropUntil(ignored -> true)).isSameAs(empty());
513         }
514     }
515 
516     @Test
517     public void shouldDropUntilNoneIfPredicateIsTrue() {
518         if (useIsEqualToInsteadOfIsSameAs()) {
519             assertThat(of(1, 2, 3).dropUntil(ignored -> true)).isEqualTo(of(1, 2, 3));
520         } else {
521             final Traversable<Integer> t = of(1, 2, 3);
522             assertThat(t.dropUntil(ignored -> true)).isSameAs(t);
523         }
524     }
525 
526     @Test
527     public void shouldDropUntilAllIfPredicateIsFalse() {
528         if (useIsEqualToInsteadOfIsSameAs()) {
529             assertThat(of(1, 2, 3).dropUntil(ignored -> false)).isEqualTo(empty());
530         } else {
531             assertThat(of(1, 2, 3).dropUntil(ignored -> false)).isSameAs(empty());
532         }
533     }
534 
535     @Test
536     public void shouldDropUntilCorrect() {
537         assertThat(of(1, 2, 3).dropUntil(i -> i >= 2)).isEqualTo(of(2, 3));
538     }
539 
540     @Test
541     public void shouldReturnSameInstanceWhenEmptyDropUntil() {
542         final Traversable<?> empty = empty();
543         assertThat(empty.dropUntil(ignored -> true)).isSameAs(empty);
544     }
545 
546     // -- dropWhile
547 
548     @Test
549     public void shouldDropWhileNoneOnNil() {
550         final Traversable<?> empty = empty();
551         final Traversable<?> actual = empty.dropWhile(ignored -> true);
552         if (useIsEqualToInsteadOfIsSameAs()) {
553             assertThat(actual).isEqualTo(empty);
554         } else {
555             assertThat(actual).isSameAs(empty);
556         }
557     }
558 
559     @Test
560     public void shouldDropWhileNoneIfPredicateIsFalse() {
561         if (useIsEqualToInsteadOfIsSameAs()) {
562             assertThat(of(1, 2, 3).dropWhile(ignored -> false)).isEqualTo(of(1, 2, 3));
563         } else {
564             final Traversable<Integer> t = of(1, 2, 3);
565             assertThat(t.dropWhile(ignored -> false)).isSameAs(t);
566         }
567     }
568 
569     @Test
570     public void shouldDropWhileAllIfPredicateIsTrue() {
571         final Traversable<Integer> actual = of(1, 2, 3).dropWhile(ignored -> true);
572         if (useIsEqualToInsteadOfIsSameAs()) {
573             assertThat(actual).isEqualTo(empty());
574         } else {
575             assertThat(actual).isSameAs(empty());
576         }
577     }
578 
579     @Test
580     public void shouldDropWhileAccordingToPredicate() {
581         assertThat(of(1, 2, 3).dropWhile(i -> i < 2)).isEqualTo(of(2, 3));
582     }
583 
584     @Test
585     public void shouldDropWhileAndNotTruncate() {
586         assertThat(of(1, 2, 3).dropWhile(i -> i % 2 == 1)).isEqualTo(of(2, 3));
587     }
588 
589     @Test
590     public void shouldReturnSameInstanceWhenEmptyDropWhile() {
591         final Traversable<?> empty = empty();
592         assertThat(empty.dropWhile(ignored -> true)).isSameAs(empty);
593     }
594 
595     // -- existsUnique
596 
597     @Test
598     public void shouldBeAwareOfExistingUniqueElement() {
599         assertThat(of(1, 2).existsUnique(i -> i == 1)).isTrue();
600     }
601 
602     @Test
603     public void shouldBeAwareOfNonExistingUniqueElement() {
604         assertThat(this.<Integer> empty().existsUnique(i -> i == 1)).isFalse();
605     }
606 
607     @Test
608     public void shouldBeAwareOfExistingNonUniqueElement() {
609         assertThat(of(1, 1, 2).existsUnique(i -> i == 1)).isFalse();
610     }
611 
612     // -- filter
613 
614     @Test
615     public void shouldFilterExistingElements() {
616         assertThat(of(1, 2, 3).filter(i -> i == 1)).isEqualTo(of(1));
617         assertThat(of(1, 2, 3).filter(i -> i == 2)).isEqualTo(of(2));
618         assertThat(of(1, 2, 3).filter(i -> i == 3)).isEqualTo(of(3));
619         if (useIsEqualToInsteadOfIsSameAs()) {
620             assertThat(of(1, 2, 3).filter(ignore -> true)).isEqualTo(of(1, 2, 3));
621         } else {
622             final Traversable<Integer> t = of(1, 2, 3);
623             assertThat(t.filter(ignore -> true)).isSameAs(t);
624         }
625     }
626 
627     @Test
628     public void shouldFilterNonExistingElements() {
629         if (useIsEqualToInsteadOfIsSameAs()) {
630             assertThat(this.<Integer> empty().filter(i -> i == 0)).isEqualTo(empty());
631             assertThat(of(1, 2, 3).filter(i -> i == 0)).isEqualTo(empty());
632         } else {
633             assertThat(this.<Integer> empty().filter(i -> i == 0)).isSameAs(empty());
634             assertThat(of(1, 2, 3).filter(i -> i == 0)).isSameAs(empty());
635         }
636     }
637 
638     @Test
639     public void shouldReturnSameInstanceWhenFilteringEmptyTraversable() {
640         final Traversable<?> empty = empty();
641         assertThat(empty.filter(v -> true)).isSameAs(empty);
642     }
643 
644     // -- find
645 
646     @Test
647     public void shouldFindFirstOfNil() {
648         assertThat(empty().find(ignored -> true)).isEqualTo(Option.none());
649     }
650 
651     @Test
652     public void shouldFindFirstOfNonNil() {
653         assertThat(of(1, 2, 3, 4).find(i -> i % 2 == 0)).isEqualTo(Option.of(2));
654     }
655 
656     // -- findLast
657 
658     @Test
659     public void shouldFindLastOfNil() {
660         assertThat(empty().findLast(ignored -> true)).isEqualTo(Option.none());
661     }
662 
663     @Test
664     public void shouldFindLastOfNonNil() {
665         assertThat(of(1, 2, 3, 4).findLast(i -> i % 2 == 0)).isEqualTo(Option.of(4));
666     }
667 
668     // -- flatMap
669 
670     @Test
671     public void shouldFlatMapEmpty() {
672         if (useIsEqualToInsteadOfIsSameAs()) {
673             assertThat(empty().flatMap(v -> of(v, 0))).isEqualTo(empty());
674         } else {
675             assertThat(empty().flatMap(v -> of(v, 0))).isSameAs(empty());
676         }
677     }
678 
679     @Test
680     public void shouldFlatMapNonEmpty() {
681         assertThat(of(1, 2, 3).flatMap(v -> of(v, 0))).isEqualTo(of(1, 0, 2, 0, 3, 0));
682     }
683 
684     // -- fold
685 
686     @Test
687     public void shouldFoldNil() {
688         assertThat(this.<String> empty().fold("", (a, b) -> a + b)).isEqualTo("");
689     }
690 
691     @Test(expected = NullPointerException.class)
692     public void shouldThrowWhenFoldNullOperator() {
693         this.<String> empty().fold(null, null);
694     }
695 
696     @Test
697     public void shouldFoldSingleElement() {
698         assertThat(of(1).fold(0, (a, b) -> a + b)).isEqualTo(1);
699     }
700 
701     @Test
702     public void shouldFoldMultipleElements() {
703         assertThat(of(1, 2, 3).fold(0, (a, b) -> a + b)).isEqualTo(6);
704     }
705 
706     // -- foldLeft
707 
708     @Test
709     public void shouldFoldLeftNil() {
710         assertThat(this.<String> empty().foldLeft("", (xs, x) -> xs + x)).isEqualTo("");
711     }
712 
713     @Test(expected = NullPointerException.class)
714     public void shouldThrowWhenFoldLeftNullOperator() {
715         this.<String> empty().foldLeft(null, null);
716     }
717 
718     @Test
719     public void shouldFoldLeftNonNil() {
720         assertThat(of("a", "b", "c").foldLeft("!", (xs, x) -> xs + x)).isEqualTo("!abc");
721     }
722 
723     // -- foldRight
724 
725     @Test
726     public void shouldFoldRightNil() {
727         assertThat(this.<String> empty().foldRight("", (x, xs) -> x + xs)).isEqualTo("");
728     }
729 
730     @Test(expected = NullPointerException.class)
731     public void shouldThrowWhenFoldRightNullOperator() {
732         this.<String> empty().foldRight(null, null);
733     }
734 
735     @Test
736     public void shouldFoldRightNonNil() {
737         assertThat(of("a", "b", "c").foldRight("!", (x, xs) -> x + xs)).isEqualTo("abc!");
738     }
739 
740     // -- groupBy
741 
742     @Test
743     public void shouldNilGroupBy() {
744         assertThat(empty().groupBy(Function.identity())).isEqualTo(LinkedHashMap.empty());
745     }
746 
747     @Test
748     public void shouldNonNilGroupByIdentity() {
749         final Map<?, ?> actual = of('a', 'b', 'c').groupBy(Function.identity());
750         final Map<?, ?> expected = LinkedHashMap.empty().put('a', of('a')).put('b', of('b')).put('c', of('c'));
751         assertThat(actual).isEqualTo(expected);
752     }
753 
754     @Test
755     public void shouldNonNilGroupByEqual() {
756         final Map<?, ?> actual = of('a', 'b', 'c').groupBy(c -> 1);
757         final Map<?, ?> expected = LinkedHashMap.empty().put(1, of('a', 'b', 'c'));
758         assertThat(actual).isEqualTo(expected);
759     }
760 
761     // -- arrangeBy
762 
763     @Test
764     public void shouldNilArrangeBy() {
765         assertThat(empty().arrangeBy(Function.identity())).isEqualTo(Option.of(LinkedHashMap.empty()));
766     }
767 
768     @Test
769     public void shouldNonNilArrangeByIdentity() {
770         final Option<Map<Character,Character>> actual = of('a', 'b', 'c').arrangeBy(Function.identity());
771         final Option<Map<?, ?>> expected = Option.of(LinkedHashMap.empty().put('a', 'a').put('b', 'b').put('c', 'c'));
772         assertThat(actual).isEqualTo(expected);
773     }
774 
775     @Test
776     public void shouldNonNilArrangeByEqual() {
777         final Option<Map<Integer, Character>> actual = of('a', 'b', 'c').arrangeBy(c -> 1);
778         final Option<Map<?, ?>> expected = Option.none();
779         assertThat(actual).isEqualTo(expected);
780     }
781 
782     // -- grouped
783 
784     @Test
785     public void shouldGroupedNil() {
786         assertThat(empty().grouped(1).isEmpty()).isTrue();
787     }
788 
789     @Test(expected = IllegalArgumentException.class)
790     public void shouldThrowWhenGroupedWithSizeZero() {
791         empty().grouped(0);
792     }
793 
794     @Test(expected = IllegalArgumentException.class)
795     public void shouldThrowWhenGroupedWithNegativeSize() {
796         empty().grouped(-1);
797     }
798 
799     @Test
800     public void shouldGroupedTraversableWithEqualSizedBlocks() {
801         final List<Traversable<Integer>> actual = of(1, 2, 3, 4).grouped(2).toList().map(io.vavr.collection.Vector::ofAll);
802         final List<Traversable<Integer>> expected = List.of(io.vavr.collection.Vector.of(1, 2), io.vavr.collection.Vector.of(3, 4));
803         assertThat(actual).isEqualTo(expected);
804     }
805 
806     @Test
807     public void shouldGroupedTraversableWithRemainder() {
808         final List<Traversable<Integer>> actual = of(1, 2, 3, 4, 5).grouped(2).toList().map(io.vavr.collection.Vector::ofAll);
809         final List<Traversable<Integer>> expected = List.of(io.vavr.collection.Vector.of(1, 2), io.vavr.collection.Vector.of(3, 4), io.vavr.collection.Vector.of(5));
810         assertThat(actual).isEqualTo(expected);
811     }
812 
813     @Test
814     public void shouldGroupedWhenTraversableLengthIsSmallerThanBlockSize() {
815         final List<Traversable<Integer>> actual = of(1, 2, 3, 4).grouped(5).toList().map(io.vavr.collection.Vector::ofAll);
816         final List<Traversable<Integer>> expected = List.of(io.vavr.collection.Vector.of(1, 2, 3, 4));
817         assertThat(actual).isEqualTo(expected);
818     }
819 
820     // -- hasDefiniteSize
821 
822     @Test
823     public void shouldReturnSomethingOnHasDefiniteSize() {
824         empty().hasDefiniteSize();
825     }
826 
827     // -- head
828 
829     @Test(expected = NoSuchElementException.class)
830     public void shouldThrowWhenHeadOnNil() {
831         empty().head();
832     }
833 
834     @Test
835     public void shouldReturnHeadOfNonNil() {
836         assertThat(of(1, 2, 3).head()).isEqualTo(1);
837     }
838 
839     // -- headOption
840 
841     @Test
842     public void shouldReturnNoneWhenCallingHeadOptionOnNil() {
843         assertThat(empty().headOption().isEmpty()).isTrue();
844     }
845 
846     @Test
847     public void shouldReturnSomeHeadWhenCallingHeadOptionOnNonNil() {
848         assertThat(of(1, 2, 3).headOption()).isEqualTo(Option.some(1));
849     }
850 
851     // -- init
852 
853     @Test(expected = UnsupportedOperationException.class)
854     public void shouldThrowWhenInitOfNil() {
855         empty().init().get();
856     }
857 
858     @Test
859     public void shouldGetInitOfNonNil() {
860         assertThat(of(1, 2, 3).init()).isEqualTo(of(1, 2));
861     }
862 
863     // -- initOption
864 
865     @Test
866     public void shouldReturnNoneWhenCallingInitOptionOnNil() {
867         assertThat(empty().initOption().isEmpty()).isTrue();
868     }
869 
870     @Test
871     public void shouldReturnSomeInitWhenCallingInitOptionOnNonNil() {
872         assertThat(of(1, 2, 3).initOption()).isEqualTo(Option.some(of(1, 2)));
873     }
874 
875     // -- isEmpty
876 
877     @Test
878     public void shouldRecognizeNil() {
879         assertThat(empty().isEmpty()).isTrue();
880     }
881 
882     @Test
883     public void shouldRecognizeNonNil() {
884         assertThat(of(1).isEmpty()).isFalse();
885     }
886 
887     // -- isTraversableAgain
888 
889     @Test
890     public void shouldReturnSomethingOnIsTraversableAgain() {
891         empty().isTraversableAgain();
892     }
893 
894     // -- iterator
895 
896     @Test
897     public void shouldNotHasNextWhenNilIterator() {
898         assertThat(empty().iterator().hasNext()).isFalse();
899     }
900 
901     @Test(expected = NoSuchElementException.class)
902     public void shouldThrowOnNextWhenNilIterator() {
903         empty().iterator().next();
904     }
905 
906     @Test
907     public void shouldIterateFirstElementOfNonNil() {
908         assertThat(of(1, 2, 3).iterator().next()).isEqualTo(1);
909     }
910 
911     @Test
912     public void shouldFullyIterateNonNil() {
913         final io.vavr.collection.Iterator<Integer> iterator = of(1, 2, 3).iterator();
914         int actual;
915         for (int i = 1; i <= 3; i++) {
916             actual = iterator.next();
917             assertThat(actual).isEqualTo(i);
918         }
919         assertThat(iterator.hasNext()).isFalse();
920     }
921 
922     @Test
923     public void shouldThrowWhenCallingNextOnEmptyIterator() {
924         assertThatThrownBy(() -> empty().iterator().next()).isInstanceOf(NoSuchElementException.class);
925     }
926 
927     @Test
928     public void shouldThrowWhenCallingNextTooOftenOnNonEmptyIterator() {
929         final io.vavr.collection.Iterator<Integer> iterator = of(1).iterator();
930         assertThatThrownBy(() -> {
931             iterator.next();
932             iterator.next();
933         }).isInstanceOf(NoSuchElementException.class);
934     }
935 
936     // -- mkString()
937 
938     @Test
939     public void shouldMkStringNil() {
940         assertThat(empty().mkString()).isEqualTo("");
941     }
942 
943     @Test
944     public void shouldMkStringNonNil() {
945         assertThat(of('a', 'b', 'c').mkString()).isEqualTo("abc");
946     }
947 
948     // -- mkString(delimiter)
949 
950     @Test
951     public void shouldMkStringWithDelimiterNil() {
952         assertThat(empty().mkString(",")).isEqualTo("");
953     }
954 
955     @Test
956     public void shouldMkStringWithDelimiterNonNil() {
957         assertThat(of('a', 'b', 'c').mkString(",")).isEqualTo("a,b,c");
958     }
959 
960     // -- mkString(delimiter, prefix, suffix)
961 
962     @Test
963     public void shouldMkStringWithDelimiterAndPrefixAndSuffixNil() {
964         assertThat(empty().mkString("[", ",", "]")).isEqualTo("[]");
965     }
966 
967     @Test
968     public void shouldMkStringWithDelimiterAndPrefixAndSuffixNonNil() {
969         assertThat(of('a', 'b', 'c').mkString("[", ",", "]")).isEqualTo("[a,b,c]");
970     }
971 
972     // -- mkCharSeq()
973 
974     @Test
975     public void shouldMkCharSeqNil() {
976         assertThat(empty().mkCharSeq()).isEqualTo(CharSeq.empty());
977     }
978 
979     @Test
980     public void shouldMkCharSeqNonNil() {
981         assertThat(of('a', 'b', 'c').mkCharSeq()).isEqualTo(CharSeq.of("abc"));
982     }
983 
984     // -- mkCharSeq(delimiter)
985 
986     @Test
987     public void shouldMkCharSeqWithDelimiterNil() {
988         assertThat(empty().mkCharSeq(",")).isEqualTo(CharSeq.empty());
989     }
990 
991     @Test
992     public void shouldMkCharSeqWithDelimiterNonNil() {
993         assertThat(of('a', 'b', 'c').mkCharSeq(",")).isEqualTo(CharSeq.of("a,b,c"));
994     }
995 
996     // -- mkCharSeq(delimiter, prefix, suffix)
997 
998     @Test
999     public void shouldMkCharSeqWithDelimiterAndPrefixAndSuffixNil() {
1000         assertThat(empty().mkCharSeq("[", ",", "]")).isEqualTo(CharSeq.of("[]"));
1001     }
1002 
1003     @Test
1004     public void shouldMkCharSeqWithDelimiterAndPrefixAndSuffixNonNil() {
1005         assertThat(of('a', 'b', 'c').mkCharSeq("[", ",", "]")).isEqualTo(CharSeq.of("[a,b,c]"));
1006     }
1007 
1008     // -- last
1009 
1010     @Test(expected = NoSuchElementException.class)
1011     public void shouldThrowWhenLastOnNil() {
1012         empty().last();
1013     }
1014 
1015     @Test
1016     public void shouldReturnLastOfNonNil() {
1017         assertThat(of(1, 2, 3).last()).isEqualTo(3);
1018     }
1019 
1020     // -- lastOption
1021 
1022     @Test
1023     public void shouldReturnNoneWhenCallingLastOptionOnNil() {
1024         assertThat(empty().lastOption().isEmpty()).isTrue();
1025     }
1026 
1027     @Test
1028     public void shouldReturnSomeLastWhenCallingLastOptionOnNonNil() {
1029         assertThat(of(1, 2, 3).lastOption()).isEqualTo(Option.some(3));
1030     }
1031 
1032     // -- length
1033 
1034     @Test
1035     public void shouldComputeLengthOfNil() {
1036         assertThat(empty().length()).isEqualTo(0);
1037     }
1038 
1039     @Test
1040     public void shouldComputeLengthOfNonNil() {
1041         assertThat(of(1, 2, 3).length()).isEqualTo(3);
1042     }
1043 
1044     // -- max
1045 
1046     @Test
1047     public void shouldReturnNoneWhenComputingMaxOfNil() {
1048         assertThat(empty().max()).isEqualTo(Option.none());
1049     }
1050 
1051     @Test
1052     public void shouldComputeMaxOfOneValue() { assertThat(of(5).max()).isEqualTo(Option.some(5)); }
1053 
1054     @Test
1055     public void shouldComputeMaxOfStrings() {
1056         assertThat(of("1", "2", "3").max()).isEqualTo(Option.some("3"));
1057     }
1058 
1059     @Test
1060     public void shouldComputeMaxOfBoolean() {
1061         assertThat(of(true, false).max()).isEqualTo(Option.some(true));
1062     }
1063 
1064     @Test
1065     public void shouldComputeMaxOfByte() {
1066         assertThat(of((byte) 1, (byte) 2).max()).isEqualTo(Option.some((byte) 2));
1067     }
1068 
1069     @Test
1070     public void shouldComputeMaxOfChar() {
1071         assertThat(of('a', 'b', 'c').max()).isEqualTo(Option.some('c'));
1072     }
1073 
1074     @Test
1075     public void shouldComputeMaxOfDouble() {
1076         assertThat(of(.1, .2, .3).max()).isEqualTo(Option.some(.3));
1077     }
1078 
1079     @Test
1080     public void shouldComputeMaxOfFloat() {
1081         assertThat(of(.1f, .2f, .3f).max()).isEqualTo(Option.some(.3f));
1082     }
1083 
1084     @Test
1085     public void shouldComputeMaxOfInt() {
1086         assertThat(of(1, 2, 3).max()).isEqualTo(Option.some(3));
1087     }
1088 
1089     @Test
1090     public void shouldComputeMaxOfLong() {
1091         assertThat(of(1L, 2L, 3L).max()).isEqualTo(Option.some(3L));
1092     }
1093 
1094     @Test
1095     public void shouldComputeMaxOfShort() {
1096         assertThat(of((short) 1, (short) 2, (short) 3).max()).isEqualTo(Option.some((short) 3));
1097     }
1098 
1099     @Test
1100     public void shouldComputeMaxOfBigInteger() {
1101         assertThat(of(BigInteger.ZERO, BigInteger.ONE).max()).isEqualTo(Option.some(BigInteger.ONE));
1102     }
1103 
1104     @Test
1105     public void shouldComputeMaxOfBigDecimal() {
1106         assertThat(of(BigDecimal.ZERO, BigDecimal.ONE).max()).isEqualTo(Option.some(BigDecimal.ONE));
1107     }
1108 
1109     @Test(expected = NullPointerException.class)
1110     public void shouldThrowNPEWhenMaxOfNullAndInt() {
1111         of(null, 1).max();
1112     }
1113 
1114     @Test(expected = NullPointerException.class)
1115     public void shouldThrowNPEWhenMaxOfIntAndNull() {
1116         of(1, null).max();
1117     }
1118 
1119     // -- maxBy(Comparator)
1120 
1121     @Test(expected = NullPointerException.class)
1122     public void shouldThrowWhenMaxByWithNullComparator() {
1123         of(1).maxBy((Comparator<Integer>) null);
1124     }
1125 
1126     @Test
1127     public void shouldThrowWhenMaxByOfNil() {
1128         assertThat(empty().maxBy((o1, o2) -> 0)).isEqualTo(Option.none());
1129     }
1130 
1131     @Test
1132     public void shouldCalculateMaxByOfInts() {
1133         assertThat(of(1, 2, 3).maxBy(comparingInt(i -> i))).isEqualTo(Option.some(3));
1134     }
1135 
1136     @Test
1137     public void shouldCalculateInverseMaxByOfInts() {
1138         assertThat(of(1, 2, 3).maxBy((i1, i2) -> i2 - i1)).isEqualTo(Option.some(1));
1139     }
1140 
1141     // -- maxBy(Function)
1142 
1143     @Test(expected = NullPointerException.class)
1144     public void shouldThrowWhenMaxByWithNullFunction() {
1145         of(1).maxBy((Function<Integer, Integer>) null);
1146     }
1147 
1148     @Test
1149     public void shouldThrowWhenMaxByFunctionOfNil() {
1150         assertThat(this.<Integer> empty().maxBy(i -> i)).isEqualTo(Option.none());
1151     }
1152 
1153     @Test
1154     public void shouldCalculateMaxByFunctionOfInts() {
1155         assertThat(of(1, 2, 3).maxBy(i -> i)).isEqualTo(Option.some(3));
1156     }
1157 
1158     @Test
1159     public void shouldCalculateInverseMaxByFunctionOfInts() {
1160         assertThat(of(1, 2, 3).maxBy(i -> -i)).isEqualTo(Option.some(1));
1161     }
1162 
1163     @Test
1164     public void shouldCallMaxFunctionOncePerElement() {
1165         final int[] cnt = { 0 };
1166         assertThat(of(1, 2, 3).maxBy(i -> {
1167             cnt[0]++;
1168             return i;
1169         })).isEqualTo(Option.some(3));
1170         assertThat(cnt[0]).isEqualTo(3);
1171     }
1172 
1173     // -- min
1174 
1175     @Test
1176     public void shouldReturnNoneWhenComputingMinOfNil() {
1177         assertThat(empty().min()).isEqualTo(Option.none());
1178     }
1179 
1180     @Test
1181     public void shouldComputeMinOfOneValue() { assertThat(of(5).min()).isEqualTo(Option.some(5)); }
1182 
1183     @Test
1184     public void shouldComputeMinOfStrings() {
1185         assertThat(of("1", "2", "3").min()).isEqualTo(Option.some("1"));
1186     }
1187 
1188     @Test
1189     public void shouldComputeMinOfBoolean() {
1190         assertThat(of(true, false).min()).isEqualTo(Option.some(false));
1191     }
1192 
1193     @Test
1194     public void shouldComputeMinOfByte() {
1195         assertThat(of((byte) 1, (byte) 2).min()).isEqualTo(Option.some((byte) 1));
1196     }
1197 
1198     @Test
1199     public void shouldComputeMinOfChar() {
1200         assertThat(of('a', 'b', 'c').min()).isEqualTo(Option.some('a'));
1201     }
1202 
1203     @Test
1204     public void shouldComputeMinOfDouble() {
1205         assertThat(of(.1, .2, .3).min()).isEqualTo(Option.some(.1));
1206     }
1207 
1208     @Test
1209     public void shouldComputeMinOfFloat() {
1210         assertThat(of(.1f, .2f, .3f).min()).isEqualTo(Option.some(.1f));
1211     }
1212 
1213     @Test
1214     public void shouldComputeMinOfInt() {
1215         assertThat(of(1, 2, 3).min()).isEqualTo(Option.some(1));
1216     }
1217 
1218     @Test
1219     public void shouldComputeMinOfLong() {
1220         assertThat(of(1L, 2L, 3L).min()).isEqualTo(Option.some(1L));
1221     }
1222 
1223     @Test
1224     public void shouldComputeMinOfShort() {
1225         assertThat(of((short) 1, (short) 2, (short) 3).min()).isEqualTo(Option.some((short) 1));
1226     }
1227 
1228     @Test
1229     public void shouldComputeMinOfBigInteger() {
1230         assertThat(of(BigInteger.ZERO, BigInteger.ONE).min()).isEqualTo(Option.some(BigInteger.ZERO));
1231     }
1232 
1233     @Test
1234     public void shouldComputeMinOfBigDecimal() {
1235         assertThat(of(BigDecimal.ZERO, BigDecimal.ONE).min()).isEqualTo(Option.some(BigDecimal.ZERO));
1236     }
1237 
1238     @Test(expected = NullPointerException.class)
1239     public void shouldThrowNPEWhenMinOfNullAndInt() {
1240         of(null, 1).min();
1241     }
1242 
1243     @Test(expected = NullPointerException.class)
1244     public void shouldThrowNPEWhenMinOfIntAndNull() {
1245         of(1, null).min();
1246     }
1247 
1248     // -- minBy(Comparator)
1249 
1250     @Test(expected = NullPointerException.class)
1251     public void shouldThrowWhenMinByWithNullComparator() {
1252         of(1).minBy((Comparator<Integer>) null);
1253     }
1254 
1255     @Test
1256     public void shouldThrowWhenMinByOfNil() {
1257         assertThat(empty().minBy((o1, o2) -> 0)).isEqualTo(Option.none());
1258     }
1259 
1260     @Test
1261     public void shouldCalculateMinByOfInts() {
1262         assertThat(of(1, 2, 3).minBy(comparingInt(i -> i))).isEqualTo(Option.some(1));
1263     }
1264 
1265     @Test
1266     public void shouldCalculateInverseMinByOfInts() {
1267         assertThat(of(1, 2, 3).minBy((i1, i2) -> i2 - i1)).isEqualTo(Option.some(3));
1268     }
1269 
1270     // -- minBy(Function)
1271 
1272     @Test(expected = NullPointerException.class)
1273     public void shouldThrowWhenMinByWithNullFunction() {
1274         of(1).minBy((Function<Integer, Integer>) null);
1275     }
1276 
1277     @Test
1278     public void shouldThrowWhenMinByFunctionOfNil() {
1279         assertThat(this.<Integer> empty().minBy(i -> i)).isEqualTo(Option.none());
1280     }
1281 
1282     @Test
1283     public void shouldCalculateMinByFunctionOfInts() {
1284         assertThat(of(1, 2, 3).minBy(i -> i)).isEqualTo(Option.some(1));
1285     }
1286 
1287     @Test
1288     public void shouldCalculateInverseMinByFunctionOfInts() {
1289         assertThat(of(1, 2, 3).minBy(i -> -i)).isEqualTo(Option.some(3));
1290     }
1291 
1292     @Test
1293     public void shouldCallMinFunctionOncePerElement() {
1294         final int[] cnt = { 0 };
1295         assertThat(of(1, 2, 3).minBy(i -> {
1296             cnt[0]++;
1297             return i;
1298         })).isEqualTo(Option.some(1));
1299         assertThat(cnt[0]).isEqualTo(3);
1300     }
1301 
1302     // -- nonEmpty
1303 
1304     @Test
1305     public void shouldCalculateNonEmpty() {
1306         assertThat(empty().nonEmpty()).isFalse();
1307         assertThat(of(1).nonEmpty()).isTrue();
1308     }
1309 
1310     // -- orElse
1311 
1312     @Test
1313     public void shouldCaclEmptyOrElseSameOther() {
1314         final Iterable<Integer> other = of(42);
1315         assertThat(empty().orElse(other)).isSameAs(other);
1316     }
1317 
1318     @Test
1319     public void shouldCaclEmptyOrElseEqualOther() {
1320         assertThat(empty().orElse(Arrays.asList(1, 2))).isEqualTo(of(1, 2));
1321     }
1322 
1323     @Test
1324     public void shouldCaclNonemptyOrElseOther() {
1325         final Traversable<Integer> src = of(42);
1326         assertThat(src.orElse(List.of(1))).isSameAs(src);
1327     }
1328 
1329     @Test
1330     public void shouldCaclEmptyOrElseSameSupplier() {
1331         final Iterable<Integer> other = of(42);
1332         final Supplier<Iterable<Integer>> supplier = () -> other;
1333         assertThat(empty().orElse(supplier)).isSameAs(other);
1334     }
1335 
1336     @Test
1337     public void shouldCaclEmptyOrElseEqualSupplier() {
1338         assertThat(empty().orElse(() -> Arrays.asList(1, 2))).isEqualTo(of(1, 2));
1339     }
1340 
1341     @Test
1342     public void shouldCaclNonemptyOrElseSupplier() {
1343         final Traversable<Integer> src = of(42);
1344         assertThat(src.orElse(() -> List.of(1))).isSameAs(src);
1345     }
1346 
1347     // -- partition
1348 
1349     @Test(expected = NullPointerException.class)
1350     public void shouldThrowWhenPartitionNilAndPredicateIsNull() {
1351         empty().partition(null);
1352     }
1353 
1354     @Test
1355     public void shouldPartitionNil() {
1356         assertThat(empty().partition(e -> true)).isEqualTo(Tuple.of(empty(), empty()));
1357     }
1358 
1359     @Test
1360     public void shouldPartitionIntsInOddAndEvenHavingOddAndEvenNumbers() {
1361         assertThat(of(1, 2, 3, 4).partition(i -> i % 2 != 0)).isEqualTo(Tuple.of(of(1, 3), of(2, 4)));
1362     }
1363 
1364     @Test
1365     public void shouldPartitionIntsInOddAndEvenHavingOnlyOddNumbers() {
1366         assertThat(of(1, 3).partition(i -> i % 2 != 0)).isEqualTo(Tuple.of(of(1, 3), empty()));
1367     }
1368 
1369     @Test
1370     public void shouldPartitionIntsInOddAndEvenHavingOnlyEvenNumbers() {
1371         assertThat(of(2, 4).partition(i -> i % 2 != 0)).isEqualTo(Tuple.of(empty(), of(2, 4)));
1372     }
1373 
1374     // -- product
1375 
1376     @Test
1377     public void shouldComputeProductOfNil() {
1378         assertThat(empty().product()).isEqualTo(1);
1379     }
1380 
1381     @Test(expected = UnsupportedOperationException.class)
1382     public void shouldThrowWhenComputingProductOfStrings() {
1383         of("1", "2", "3").product();
1384     }
1385 
1386     @Test
1387     public void shouldComputeProductOfByte() {
1388         assertThat(of((byte) 1, (byte) 2).product()).isEqualTo(2L);
1389     }
1390 
1391     @Test
1392     public void shouldComputeProductOfDouble() {
1393         assertThat(of(.1, .2, .3).product().doubleValue()).isEqualTo(.006, within(10e-18));
1394     }
1395 
1396     @Test
1397     public void shouldComputeProductOfFloat() {
1398         assertThat(of(.1f, .2f, .3f).product().doubleValue()).isEqualTo(.006, within(10e-10));
1399     }
1400 
1401     @Test
1402     public void shouldComputeProductOfInt() {
1403         assertThat(of(1, 2, 3).product()).isEqualTo(6L);
1404     }
1405 
1406     @Test
1407     public void shouldComputeProductOfLong() {
1408         assertThat(of(1L, 2L, 3L).product()).isEqualTo(6L);
1409     }
1410 
1411     @Test
1412     public void shouldComputeProductOfShort() {
1413         assertThat(of((short) 1, (short) 2, (short) 3).product()).isEqualTo(6L);
1414     }
1415 
1416     @Test
1417     public void shouldComputeProductOfBigInteger() {
1418         assertThat(of(BigInteger.ZERO, BigInteger.ONE).product()).isEqualTo(0L);
1419     }
1420 
1421     @Test
1422     public void shouldComputeProductOfBigDecimal() {
1423         assertThat(of(BigDecimal.ZERO, BigDecimal.ONE).product()).isEqualTo(0.0);
1424     }
1425 
1426     // -- reduceOption
1427 
1428     @Test
1429     public void shouldThrowWhenReduceOptionNil() {
1430         assertThat(this.<String> empty().reduceOption((a, b) -> a + b)).isSameAs(Option.none());
1431     }
1432 
1433     @Test(expected = NullPointerException.class)
1434     public void shouldThrowWhenReduceOptionNullOperator() {
1435         this.<String> empty().reduceOption(null);
1436     }
1437 
1438     @Test
1439     public void shouldReduceOptionNonNil() {
1440         assertThat(of(1, 2, 3).reduceOption((a, b) -> a + b)).isEqualTo(Option.of(6));
1441     }
1442 
1443     // -- reduce
1444 
1445     @Test(expected = NoSuchElementException.class)
1446     public void shouldThrowWhenReduceNil() {
1447         this.<String> empty().reduce((a, b) -> a + b);
1448     }
1449 
1450     @Test(expected = NullPointerException.class)
1451     public void shouldThrowWhenReduceNullOperator() {
1452         this.<String> empty().reduce(null);
1453     }
1454 
1455     @Test
1456     public void shouldReduceNonNil() {
1457         assertThat(of(1, 2, 3).reduce((a, b) -> a + b)).isEqualTo(6);
1458     }
1459 
1460     // -- reduceLeftOption
1461 
1462     @Test
1463     public void shouldThrowWhenReduceLeftOptionNil() {
1464         assertThat(this.<String> empty().reduceLeftOption((a, b) -> a + b)).isSameAs(Option.none());
1465     }
1466 
1467     @Test(expected = NullPointerException.class)
1468     public void shouldThrowWhenReduceLeftOptionNullOperator() {
1469         this.<String> empty().reduceLeftOption(null);
1470     }
1471 
1472     @Test
1473     public void shouldReduceLeftOptionNonNil() {
1474         assertThat(of("a", "b", "c").reduceLeftOption((xs, x) -> xs + x)).isEqualTo(Option.of("abc"));
1475     }
1476 
1477     // -- reduceLeft
1478 
1479     @Test(expected = NoSuchElementException.class)
1480     public void shouldThrowWhenReduceLeftNil() {
1481         this.<String> empty().reduceLeft((a, b) -> a + b);
1482     }
1483 
1484     @Test(expected = NullPointerException.class)
1485     public void shouldThrowWhenReduceLeftNullOperator() {
1486         this.<String> empty().reduceLeft(null);
1487     }
1488 
1489     @Test
1490     public void shouldReduceLeftNonNil() {
1491         assertThat(of("a", "b", "c").reduceLeft((xs, x) -> xs + x)).isEqualTo("abc");
1492     }
1493 
1494     // -- reduceRightOption
1495 
1496     @Test
1497     public void shouldThrowWhenReduceRightOptionNil() {
1498         assertThat(this.<String> empty().reduceRightOption((a, b) -> a + b)).isSameAs(Option.none());
1499     }
1500 
1501     @Test(expected = NullPointerException.class)
1502     public void shouldThrowWhenReduceRightOptionNullOperator() {
1503         this.<String> empty().reduceRightOption(null);
1504     }
1505 
1506     @Test
1507     public void shouldReduceRightOptionNonNil() {
1508         assertThat(of("a", "b", "c").reduceRightOption((x, xs) -> x + xs)).isEqualTo(Option.of("abc"));
1509     }
1510 
1511     // -- reduceRight
1512 
1513     @Test(expected = NoSuchElementException.class)
1514     public void shouldThrowWhenReduceRightNil() {
1515         this.<String> empty().reduceRight((a, b) -> a + b);
1516     }
1517 
1518     @Test(expected = NullPointerException.class)
1519     public void shouldThrowWhenReduceRightNullOperator() {
1520         this.<String> empty().reduceRight(null);
1521     }
1522 
1523     @Test
1524     public void shouldReduceRightNonNil() {
1525         assertThat(of("a", "b", "c").reduceRight((x, xs) -> x + xs)).isEqualTo("abc");
1526     }
1527 
1528     // -- replace(curr, new)
1529 
1530     @Test
1531     public void shouldReplaceElementOfNilUsingCurrNew() {
1532         if (useIsEqualToInsteadOfIsSameAs()) {
1533             assertThat(this.<Integer> empty().replace(1, 2)).isEqualTo(empty());
1534         } else {
1535             assertThat(this.<Integer> empty().replace(1, 2)).isSameAs(empty());
1536         }
1537     }
1538 
1539     @Test
1540     public void shouldReplaceFirstOccurrenceOfNonNilUsingCurrNewWhenMultipleOccurrencesExist() {
1541         final Traversable<Integer> testee = of(0, 1, 2, 1);
1542         final Traversable<Integer> actual = testee.replace(1, 3);
1543         final Traversable<Integer> expected = of(0, 3, 2, 1);
1544         assertThat(actual).isEqualTo(expected);
1545     }
1546 
1547     @Test
1548     public void shouldReplaceElementOfNonNilUsingCurrNewWhenOneOccurrenceExists() {
1549         assertThat(of(0, 1, 2).replace(1, 3)).isEqualTo(of(0, 3, 2));
1550     }
1551 
1552     @Test
1553     public void shouldReplaceElementOfNonNilUsingCurrNewWhenNoOccurrenceExists() {
1554         if (useIsEqualToInsteadOfIsSameAs()) {
1555             assertThat(of(0, 1, 2).replace(33, 3)).isEqualTo(of(0, 1, 2));
1556         } else {
1557             final Traversable<Integer> src = of(0, 1, 2);
1558             assertThat(src.replace(33, 3)).isSameAs(src);
1559         }
1560     }
1561 
1562     // -- replaceAll(curr, new)
1563 
1564     @Test
1565     public void shouldReplaceAllElementsOfNilUsingCurrNew() {
1566         if (useIsEqualToInsteadOfIsSameAs()) {
1567             assertThat(this.<Integer> empty().replaceAll(1, 2)).isEqualTo(empty());
1568         } else {
1569             assertThat(this.<Integer> empty().replaceAll(1, 2)).isSameAs(empty());
1570         }
1571     }
1572 
1573     @Test
1574     public void shouldReplaceAllElementsOfNonNilUsingCurrNonExistingNew() {
1575         if (useIsEqualToInsteadOfIsSameAs()) {
1576             assertThat(of(0, 1, 2, 1).replaceAll(33, 3)).isEqualTo(of(0, 1, 2, 1));
1577         } else {
1578             final Traversable<Integer> src = of(0, 1, 2, 1);
1579             assertThat(src.replaceAll(33, 3)).isSameAs(src);
1580         }
1581     }
1582 
1583     @Test
1584     public void shouldReplaceAllElementsOfNonNilUsingCurrNew() {
1585         assertThat(of(0, 1, 2, 1).replaceAll(1, 3)).isEqualTo(of(0, 3, 2, 3));
1586     }
1587 
1588     // -- retainAll
1589 
1590     @Test
1591     public void shouldRetainAllElementsFromNil() {
1592         final Traversable<Object> empty = empty();
1593         final Traversable<Object> actual = empty.retainAll(of(1, 2, 3));
1594         if (useIsEqualToInsteadOfIsSameAs()) {
1595             assertThat(actual).isEqualTo(empty);
1596         } else {
1597             assertThat(actual).isSameAs(empty);
1598         }
1599     }
1600 
1601     @Test
1602     public void shouldRetainAllExistingElementsFromNonNil() {
1603         final Traversable<Integer> src = of(1, 2, 3, 2, 1, 3);
1604         final Traversable<Integer> expected = of(1, 2, 2, 1);
1605         final Traversable<Integer> actual = src.retainAll(of(1, 2));
1606         assertThat(actual).isEqualTo(expected);
1607     }
1608 
1609     @Test
1610     public void shouldRetainAllElementsFromNonNil() {
1611         final Traversable<Integer> src = of(1, 2, 1, 2, 2);
1612         final Traversable<Integer> expected = of(1, 2, 1, 2, 2);
1613         final Traversable<Integer> actual = src.retainAll(of(1, 2));
1614         if (useIsEqualToInsteadOfIsSameAs()) {
1615             assertThat(actual).isEqualTo(expected);
1616         } else {
1617             assertThat(actual).isSameAs(src);
1618         }
1619     }
1620 
1621     @Test
1622     public void shouldNotRetainAllNonExistingElementsFromNonNil() {
1623         final Traversable<Integer> src = of(1, 2, 3);
1624         final Traversable<Object> expected = empty();
1625         final Traversable<Integer> actual = src.retainAll(of(4, 5));
1626         if (useIsEqualToInsteadOfIsSameAs()) {
1627             assertThat(actual).isEqualTo(expected);
1628         } else {
1629             assertThat(actual).isSameAs(expected);
1630         }
1631     }
1632 
1633     // -- scan, scanLeft, scanRight
1634 
1635     @Test
1636     public void shouldScanEmpty() {
1637         final Traversable<Integer> testee = empty();
1638         final Traversable<Integer> actual = testee.scan(0, (s1, s2) -> s1 + s2);
1639         assertThat(actual).isEqualTo(this.of(0));
1640     }
1641 
1642     @Test
1643     public void shouldScanLeftEmpty() {
1644         final Traversable<Integer> testee = empty();
1645         final Traversable<Integer> actual = testee.scanLeft(0, (s1, s2) -> s1 + s2);
1646         assertThat(actual).isEqualTo(of(0));
1647     }
1648 
1649     @Test
1650     public void shouldScanRightEmpty() {
1651         final Traversable<Integer> testee = empty();
1652         final Traversable<Integer> actual = testee.scanRight(0, (s1, s2) -> s1 + s2);
1653         assertThat(actual).isEqualTo(of(0));
1654     }
1655 
1656     @Test
1657     public void shouldScanNonEmpty() {
1658         final Traversable<Integer> testee = of(1, 2, 3);
1659         final Traversable<Integer> actual = testee.scan(0, (acc, s) -> acc + s);
1660         assertThat(actual).isEqualTo(of(0, 1, 3, 6));
1661     }
1662 
1663     @Test
1664     public void shouldScanLeftNonEmpty() {
1665         final Traversable<Integer> testee = of(1, 2, 3);
1666         final Traversable<String> actual = testee.scanLeft("x", (acc, i) -> acc + i);
1667         assertThat(actual).isEqualTo(of("x", "x1", "x12", "x123"));
1668     }
1669 
1670     @Test
1671     public void shouldScanRightNonEmpty() {
1672         final Traversable<Integer> testee = of(1, 2, 3);
1673         final Traversable<String> actual = testee.scanRight("x", (i, acc) -> acc + i);
1674         assertThat(actual).isEqualTo(of("x321", "x32", "x3", "x"));
1675     }
1676 
1677     @Test
1678     public void shouldScanWithNonComparable() {
1679         final Traversable<NonComparable> testee = of(new NonComparable("a"));
1680         final List<NonComparable> actual = List.ofAll(testee.scan(new NonComparable("x"), (u1, u2) -> new NonComparable(u1.value + u2.value)));
1681         final List<NonComparable> expected = List.of("x", "xa").map(NonComparable::new);
1682         assertThat(actual).containsAll(expected);
1683         assertThat(expected).containsAll(actual);
1684         assertThat(actual.length()).isEqualTo(expected.length());
1685     }
1686 
1687     @Test
1688     public void shouldScanLeftWithNonComparable() {
1689         final Traversable<NonComparable> testee = of(new NonComparable("a"));
1690         final List<NonComparable> actual = List.ofAll(testee.scanLeft(new NonComparable("x"), (u1, u2) -> new NonComparable(u1.value + u2.value)));
1691         final List<NonComparable> expected = List.of("x", "xa").map(NonComparable::new);
1692         assertThat(actual).containsAll(expected);
1693         assertThat(expected).containsAll(actual);
1694         assertThat(actual.length()).isEqualTo(expected.length());
1695     }
1696 
1697     @Test
1698     public void shouldScanRightWithNonComparable() {
1699         final Traversable<NonComparable> testee = of(new NonComparable("a"));
1700         final List<NonComparable> actual = List.ofAll(testee.scanRight(new NonComparable("x"), (u1, u2) -> new NonComparable(u1.value + u2.value)));
1701         final List<NonComparable> expected = List.of("ax", "x").map(NonComparable::new);
1702         assertThat(actual).containsAll(expected);
1703         assertThat(expected).containsAll(actual);
1704         assertThat(actual.length()).isEqualTo(expected.length());
1705     }
1706 
1707     // -- slideBy(classifier)
1708 
1709     @Test
1710     public void shouldSlideNilByClassifier() {
1711         assertThat(empty().slideBy(Function.identity())).isEmpty();
1712     }
1713 
1714     @Test
1715     public void shouldSlideSingularByClassifier() {
1716         final List<Traversable<Integer>> actual = of(1).slideBy(Function.identity()).toList().map(io.vavr.collection.Vector::ofAll);
1717         final List<Traversable<Integer>> expected = List.of(io.vavr.collection.Vector.of(1));
1718         assertThat(actual).isEqualTo(expected);
1719     }
1720 
1721     @Test
1722     public void shouldSlideNonNilByIdentityClassifier() {
1723         final List<Traversable<Integer>> actual = of(1, 2, 3).slideBy(Function.identity()).toList().map(io.vavr.collection.Vector::ofAll);
1724         final List<Traversable<Integer>> expected = List.of(io.vavr.collection.Vector.of(1), io.vavr.collection.Vector.of(2), io.vavr.collection.Vector.of(3));
1725         assertThat(actual).isEqualTo(expected);
1726     }
1727 
1728     @Test
1729     public void shouldSlideNonNilByConstantClassifier() {
1730         final List<Traversable<Integer>> actual = of(1, 2, 3).slideBy(e -> "same").toList().map(io.vavr.collection.Vector::ofAll);
1731         final List<Traversable<Integer>> expected = List.of(io.vavr.collection.Vector.of(1, 2, 3));
1732         assertThat(actual).isEqualTo(expected);
1733     }
1734 
1735     @Test
1736     public void shouldSlideNonNilBySomeClassifier() {
1737         final List<Traversable<Integer>> actual = of(10, 20, 30, 42, 52, 60, 72).slideBy(e -> e % 10).toList().map(io.vavr.collection.Vector::ofAll);
1738         final List<Traversable<Integer>> expected = List.of(io.vavr.collection.Vector.of(10, 20, 30), io.vavr.collection.Vector.of(42, 52), io.vavr.collection.Vector.of(60), io.vavr.collection.Vector.of(72));
1739         assertThat(actual).isEqualTo(expected);
1740     }
1741 
1742     // -- sliding(size)
1743 
1744     @Test(expected = IllegalArgumentException.class)
1745     public void shouldThrowWhenSlidingNilByZeroSize() {
1746         empty().sliding(0);
1747     }
1748 
1749     @Test(expected = IllegalArgumentException.class)
1750     public void shouldThrowWhenSlidingNilByNegativeSize() {
1751         empty().sliding(-1);
1752     }
1753 
1754     @Test(expected = IllegalArgumentException.class)
1755     public void shouldThrowWhenSlidingNonNilByZeroSize() {
1756         of(1).sliding(0);
1757     }
1758 
1759     @Test(expected = IllegalArgumentException.class)
1760     public void shouldThrowWhenSlidingNonNilByNegativeSize() {
1761         of(1).sliding(-1);
1762     }
1763 
1764     @Test
1765     public void shouldSlideNilBySize() {
1766         assertThat(empty().sliding(1)).isEmpty();
1767     }
1768 
1769     @Test
1770     public void shouldSlideNonNilBySize1() {
1771         final List<Traversable<Integer>> actual = of(1, 2, 3).sliding(1).toList().map(io.vavr.collection.Vector::ofAll);
1772         final List<Traversable<Integer>> expected = List.of(io.vavr.collection.Vector.of(1), io.vavr.collection.Vector.of(2), io.vavr.collection.Vector.of(3));
1773         assertThat(actual).isEqualTo(expected);
1774     }
1775 
1776     @Test
1777     public void shouldSlideNonNilBySize2() {
1778         final List<Traversable<Integer>> actual = of(1, 2, 3, 4, 5).sliding(2).toList().map(io.vavr.collection.Vector::ofAll);
1779         final List<Traversable<Integer>> expected = List.of(io.vavr.collection.Vector.of(1, 2), io.vavr.collection.Vector.of(2, 3), io.vavr.collection.Vector.of(3, 4), io.vavr.collection.Vector.of(4, 5));
1780         assertThat(actual).isEqualTo(expected);
1781     }
1782 
1783     // -- sliding(size, step)
1784 
1785     @Test(expected = IllegalArgumentException.class)
1786     public void shouldThrowWhenSlidingNilByPositiveStepAndNegativeSize() {
1787         empty().sliding(-1, 1);
1788     }
1789 
1790     @Test(expected = IllegalArgumentException.class)
1791     public void shouldThrowWhenSlidingNilByNegativeStepAndNegativeSize() {
1792         empty().sliding(-1, -1);
1793     }
1794 
1795     @Test(expected = IllegalArgumentException.class)
1796     public void shouldThrowWhenSlidingNilByNegativeStepAndPositiveSize() {
1797         empty().sliding(1, -1);
1798     }
1799 
1800     @Test
1801     public void shouldSlideNilBySizeAndStep() {
1802         assertThat(empty().sliding(1, 1).isEmpty()).isTrue();
1803     }
1804 
1805     @Test
1806     public void shouldSlide5ElementsBySize2AndStep3() {
1807         final List<Traversable<Integer>> actual = of(1, 2, 3, 4, 5).sliding(2, 3).toList().map(io.vavr.collection.Vector::ofAll);
1808         final List<Traversable<Integer>> expected = List.of(io.vavr.collection.Vector.of(1, 2), io.vavr.collection.Vector.of(4, 5));
1809         assertThat(actual).isEqualTo(expected);
1810     }
1811 
1812     @Test
1813     public void shouldSlide5ElementsBySize2AndStep4() {
1814         final List<Traversable<Integer>> actual = of(1, 2, 3, 4, 5).sliding(2, 4).toList().map(io.vavr.collection.Vector::ofAll);
1815         final List<Traversable<Integer>> expected = List.of(io.vavr.collection.Vector.of(1, 2), io.vavr.collection.Vector.of(5));
1816         assertThat(actual).isEqualTo(expected);
1817     }
1818 
1819     @Test
1820     public void shouldSlide5ElementsBySize2AndStep5() {
1821         final List<Traversable<Integer>> actual = of(1, 2, 3, 4, 5).sliding(2, 5).toList().map(io.vavr.collection.Vector::ofAll);
1822         final List<Traversable<Integer>> expected = List.of(io.vavr.collection.Vector.of(1, 2));
1823         assertThat(actual).isEqualTo(expected);
1824     }
1825 
1826     @Test
1827     public void shouldSlide4ElementsBySize5AndStep3() {
1828         final List<Traversable<Integer>> actual = of(1, 2, 3, 4).sliding(5, 3).toList().map(io.vavr.collection.Vector::ofAll);
1829         final List<Traversable<Integer>> expected = List.of(io.vavr.collection.Vector.of(1, 2, 3, 4));
1830         assertThat(actual).isEqualTo(expected);
1831     }
1832 
1833     @Test
1834     public void shouldSlide7ElementsBySize1AndStep3() {
1835         final List<Traversable<Integer>> actual = of(1, 2, 3, 4, 5, 6 ,7).sliding(1, 3).toList().map(io.vavr.collection.Vector::ofAll);
1836         final List<Traversable<Integer>> expected = List.of(io.vavr.collection.Vector.of(1), io.vavr.collection.Vector.of(4), io.vavr.collection.Vector.of(7));
1837         assertThat(actual).isEqualTo(expected);
1838     }
1839 
1840     @Test
1841     public void shouldSlide7ElementsBySize2AndStep3() {
1842         final List<Traversable<Integer>> actual = of(1, 2, 3, 4, 5, 6 ,7).sliding(2, 3).toList().map(io.vavr.collection.Vector::ofAll);
1843         final List<Traversable<Integer>> expected = List.of(io.vavr.collection.Vector.of(1, 2), io.vavr.collection.Vector.of(4, 5), io.vavr.collection.Vector.of(7));
1844         assertThat(actual).isEqualTo(expected);
1845     }
1846 
1847     // -- span
1848 
1849     @Test
1850     public void shouldSpanNil() {
1851         assertThat(this.<Integer> empty().span(i -> i < 2)).isEqualTo(Tuple.of(empty(), empty()));
1852     }
1853 
1854     @Test
1855     public void shouldSpanNonNil() {
1856         assertThat(of(0, 1, 2, 3).span(i -> i < 2)).isEqualTo(Tuple.of(of(0, 1), of(2, 3)));
1857     }
1858 
1859     @Test
1860     public void shouldSpanAndNotTruncate() {
1861         assertThat(of(1, 1, 2, 2, 3, 3).span(x -> x % 2 == 1)).isEqualTo(Tuple.of(of(1, 1), of(2, 2, 3, 3)));
1862         assertThat(of(1, 1, 2, 2, 4, 4).span(x -> x == 1)).isEqualTo(Tuple.of(of(1, 1), of(2, 2, 4, 4)));
1863     }
1864 
1865     // -- spliterator
1866 
1867     @Test
1868     public void shouldSplitNil() {
1869         final java.util.List<Integer> actual = new java.util.ArrayList<>();
1870         this.<Integer>empty().spliterator().forEachRemaining(actual::add);
1871         assertThat(actual).isEmpty();
1872     }
1873 
1874     @Test
1875     public void shouldSplitNonNil() {
1876         final java.util.List<Integer> actual = new java.util.ArrayList<>();
1877         of(1, 2, 3).spliterator().forEachRemaining(actual::add);
1878         assertThat(actual).isEqualTo(asList(1, 2, 3));
1879     }
1880 
1881     @Test
1882     public void shouldHaveImmutableSpliterator() {
1883         assertThat(of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.IMMUTABLE)).isTrue();
1884     }
1885 
1886     // -- stderr
1887 
1888     private final static Object STD_ERR_LOCK = new Object();
1889 
1890     @Test
1891     public void shouldWriteToStderr() {
1892         synchronized (STD_ERR_LOCK) {
1893             of(1, 2, 3).stderr();
1894         }
1895     }
1896 
1897     @Test(expected = IllegalStateException.class)
1898     public void shouldHandleStderrIOException() {
1899         synchronized (STD_ERR_LOCK) {
1900             final PrintStream originalErr = System.err;
1901             try (PrintStream failingPrintStream = failingPrintStream()) {
1902                 System.setErr(failingPrintStream);
1903                 of(0).stderr();
1904             } finally {
1905                 System.setErr(originalErr);
1906             }
1907         }
1908     }
1909 
1910     // -- stdout
1911 
1912     private final static Object STD_OUT_LOCK = new Object();
1913 
1914     @Test
1915     public void shouldWriteToStdout() {
1916         synchronized (STD_OUT_LOCK) {
1917             of(1, 2, 3).stdout();
1918         }
1919     }
1920 
1921     @Test(expected = IllegalStateException.class)
1922     public void shouldHandleStdoutIOException() {
1923         synchronized (STD_OUT_LOCK) {
1924             final PrintStream originalOut = System.out;
1925             try (PrintStream failingPrintStream = failingPrintStream()) {
1926                 System.setOut(failingPrintStream);
1927                 of(0).stdout();
1928             } finally {
1929                 System.setOut(originalOut);
1930             }
1931         }
1932     }
1933 
1934     // -- PrintStream
1935 
1936     @Test
1937     public void shouldWriteToPrintStream() {
1938         final ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
1939         final PrintStream out = new PrintStream(baos);
1940         of(1, 2, 3).out(out);
1941         assertThat(baos.toString()).isEqualTo(of(1, 2, 3).mkString("", lineSeparator(), lineSeparator()));
1942     }
1943 
1944     @Test(expected = IllegalStateException.class)
1945     public void shouldHandlePrintStreamIOException() {
1946         try (PrintStream failingPrintStream = failingPrintStream()) {
1947             of(0).out(failingPrintStream);
1948         }
1949     }
1950 
1951     // -- PrintWriter
1952 
1953     @Test
1954     public void shouldWriteToPrintWriter() {
1955         final StringWriter sw = new StringWriter();
1956         final PrintWriter out = new PrintWriter(sw);
1957         of(1, 2, 3).out(out);
1958         assertThat(sw.toString()).isEqualTo(of(1, 2, 3).mkString("", lineSeparator(), lineSeparator()));
1959     }
1960 
1961     @Test(expected = IllegalStateException.class)
1962     public void shouldHandlePrintWriterIOException() {
1963         try (PrintWriter failingPrintWriter = failingPrintWriter()) {
1964             of(0).out(failingPrintWriter);
1965         }
1966     }
1967 
1968     // -- sum
1969 
1970     @Test
1971     public void shouldComputeSumOfNil() {
1972         assertThat(empty().sum()).isEqualTo(0);
1973     }
1974 
1975     @Test(expected = UnsupportedOperationException.class)
1976     public void shouldThrowWhenComputingSumOfStrings() {
1977         of("1", "2", "3").sum();
1978     }
1979 
1980     @Test
1981     public void shouldComputeSumOfByte() {
1982         assertThat(of((byte) 1, (byte) 2).sum()).isEqualTo(3L);
1983     }
1984 
1985     @Test
1986     public void shouldComputeSumOfDouble() {
1987         assertThat(of(.1, .2, .3).sum().doubleValue()).isEqualTo(.6, within(10e-16));
1988     }
1989 
1990     @Test
1991     public void shouldComputeSumOfFloat() {
1992         assertThat(of(.1f, .2f, .3f).sum().doubleValue()).isEqualTo(.6, within(10e-8));
1993     }
1994 
1995     @Test
1996     public void shouldComputeSumOfInt() {
1997         assertThat(of(1, 2, 3).sum()).isEqualTo(6L);
1998     }
1999 
2000     @Test
2001     public void shouldComputeSumOfLong() {
2002         assertThat(of(1L, 2L, 3L).sum()).isEqualTo(6L);
2003     }
2004 
2005     @Test
2006     public void shouldComputeSumOfShort() {
2007         assertThat(of((short) 1, (short) 2, (short) 3).sum()).isEqualTo(6L);
2008     }
2009 
2010     @Test
2011     public void shouldComputeSumOfBigInteger() {
2012         assertThat(of(BigInteger.ZERO, BigInteger.ONE).sum()).isEqualTo(1L);
2013     }
2014 
2015     @Test
2016     public void shouldComputeSumOfBigDecimal() {
2017         assertThat(of(BigDecimal.ZERO, BigDecimal.ONE).sum()).isEqualTo(1.0);
2018     }
2019 
2020     // -- take
2021 
2022     @Test
2023     public void shouldTakeNoneOnNil() {
2024         if (useIsEqualToInsteadOfIsSameAs()) {
2025             assertThat(empty().take(1)).isEqualTo(empty());
2026         } else {
2027             assertThat(empty().take(1)).isSameAs(empty());
2028         }
2029     }
2030 
2031     @Test
2032     public void shouldTakeNoneIfCountIsNegative() {
2033         if (useIsEqualToInsteadOfIsSameAs()) {
2034             assertThat(of(1, 2, 3).take(-1)).isEqualTo(empty());
2035         } else {
2036             assertThat(of(1, 2, 3).take(-1)).isSameAs(empty());
2037         }
2038     }
2039 
2040     @Test
2041     public void shouldTakeAsExpectedIfCountIsLessThanSize() {
2042         assertThat(of(1, 2, 3).take(2)).isEqualTo(of(1, 2));
2043     }
2044 
2045     @Test
2046     public void shouldTakeAllIfCountExceedsSize() {
2047         if (useIsEqualToInsteadOfIsSameAs()) {
2048             assertThat(of(1, 2, 3).take(4)).isEqualTo(of(1, 2, 3));
2049         } else {
2050             final Traversable<Integer> t = of(1, 2, 3);
2051             assertThat(t.take(4)).isSameAs(t);
2052         }
2053     }
2054 
2055     @Test
2056     public void shouldReturnSameInstanceIfTakeAll() {
2057         final Traversable<?> t = of(1, 2, 3);
2058         assertThat(t.take(3)).isSameAs(t);
2059         assertThat(t.take(4)).isSameAs(t);
2060     }
2061 
2062     // -- takeRight
2063 
2064     @Test
2065     public void shouldTakeRightNoneOnNil() {
2066         if (useIsEqualToInsteadOfIsSameAs()) {
2067             assertThat(empty().takeRight(1)).isEqualTo(empty());
2068         } else {
2069             assertThat(empty().takeRight(1)).isSameAs(empty());
2070         }
2071     }
2072 
2073     @Test
2074     public void shouldTakeRightNoneIfCountIsNegative() {
2075         if (useIsEqualToInsteadOfIsSameAs()) {
2076             assertThat(of(1, 2, 3).takeRight(-1)).isEqualTo(empty());
2077         } else {
2078             assertThat(of(1, 2, 3).takeRight(-1)).isSameAs(empty());
2079         }
2080     }
2081 
2082     @Test
2083     public void shouldTakeRightAsExpectedIfCountIsLessThanSize() {
2084         assertThat(of(1, 2, 3).takeRight(2)).isEqualTo(of(2, 3));
2085     }
2086 
2087     @Test
2088     public void shouldTakeRightAllIfCountExceedsSize() {
2089         if (useIsEqualToInsteadOfIsSameAs()) {
2090             assertThat(of(1, 2, 3).takeRight(4)).isEqualTo(of(1, 2, 3));
2091         } else {
2092             final Traversable<Integer> t = of(1, 2, 3);
2093             assertThat(t.takeRight(4)).isSameAs(t);
2094         }
2095     }
2096 
2097     @Test
2098     public void shouldReturnSameInstanceIfTakeRightAll() {
2099         final Traversable<?> t = of(1, 2, 3);
2100         assertThat(t.takeRight(3)).isSameAs(t);
2101         assertThat(t.takeRight(4)).isSameAs(t);
2102     }
2103 
2104     // -- takeUntil
2105 
2106     @Test
2107     public void shouldTakeUntilNoneOnNil() {
2108         if (useIsEqualToInsteadOfIsSameAs()) {
2109             assertThat(empty().takeUntil(x -> true)).isEqualTo(empty());
2110         } else {
2111             assertThat(empty().takeUntil(x -> true)).isSameAs(empty());
2112         }
2113     }
2114 
2115     @Test
2116     public void shouldTakeUntilAllOnFalseCondition() {
2117         final Traversable<Integer> t = of(1, 2, 3);
2118         if (useIsEqualToInsteadOfIsSameAs()) {
2119             assertThat(of(1, 2, 3).takeUntil(x -> false)).isEqualTo(of(1, 2, 3));
2120         } else {
2121             assertThat(t.takeUntil(x -> false)).isSameAs(t);
2122         }
2123     }
2124 
2125     @Test
2126     public void shouldTakeUntilAllOnTrueCondition() {
2127         if (useIsEqualToInsteadOfIsSameAs()) {
2128             assertThat(of(1, 2, 3).takeUntil(x -> true)).isEqualTo(empty());
2129         } else {
2130             assertThat(of(1, 2, 3).takeUntil(x -> true)).isSameAs(empty());
2131         }
2132     }
2133 
2134     @Test
2135     public void shouldTakeUntilAsExpected() {
2136         assertThat(of(2, 4, 5, 6).takeUntil(x -> x % 2 != 0)).isEqualTo(of(2, 4));
2137     }
2138 
2139     @Test
2140     public void shouldReturnSameInstanceWhenEmptyTakeUntil() {
2141         final Traversable<?> empty = empty();
2142         assertThat(empty.takeUntil(ignored -> false)).isSameAs(empty);
2143     }
2144 
2145     // -- takeWhile
2146 
2147     @Test
2148     public void shouldTakeWhileNoneOnNil() {
2149         if (useIsEqualToInsteadOfIsSameAs()) {
2150             assertThat(empty().takeWhile(x -> true)).isEqualTo(empty());
2151         } else {
2152             assertThat(empty().takeWhile(x -> true)).isSameAs(empty());
2153         }
2154     }
2155 
2156     @Test
2157     public void shouldTakeWhileAllOnFalseCondition() {
2158         if (useIsEqualToInsteadOfIsSameAs()) {
2159             assertThat(of(1, 2, 3).takeWhile(x -> false)).isEqualTo(empty());
2160         } else {
2161             assertThat(of(1, 2, 3).takeWhile(x -> false)).isSameAs(empty());
2162         }
2163     }
2164 
2165     @Test
2166     public void shouldTakeWhileAllOnTrueCondition() {
2167         final Traversable<Integer> t = of(1, 2, 3);
2168         if (useIsEqualToInsteadOfIsSameAs()) {
2169             assertThat(of(1, 2, 3).takeWhile(x -> true)).isEqualTo(of(1, 2, 3));
2170         } else {
2171             assertThat(t.takeWhile(x -> true)).isSameAs(t);
2172         }
2173     }
2174 
2175     @Test
2176     public void shouldTakeWhileAsExpected() {
2177         assertThat(of(2, 4, 5, 6).takeWhile(x -> x % 2 == 0)).isEqualTo(of(2, 4));
2178     }
2179 
2180     @Test
2181     public void shouldReturnSameInstanceWhenEmptyTakeWhile() {
2182         final Traversable<?> empty = empty();
2183         assertThat(empty.takeWhile(ignored -> false)).isSameAs(empty);
2184     }
2185 
2186     // -- tail
2187 
2188     @Test(expected = UnsupportedOperationException.class)
2189     public void shouldThrowWhenTailOnNil() {
2190         empty().tail();
2191     }
2192 
2193     @Test
2194     public void shouldReturnTailOfNonNil() {
2195         assertThat(of(1, 2, 3).tail()).isEqualTo(of(2, 3));
2196     }
2197 
2198     // -- tailOption
2199 
2200     @Test
2201     public void shouldReturnNoneWhenCallingTailOptionOnNil() {
2202         assertThat(empty().tailOption().isEmpty()).isTrue();
2203     }
2204 
2205     @Test
2206     public void shouldReturnSomeTailWhenCallingTailOptionOnNonNil() {
2207         assertThat(of(1, 2, 3).tailOption()).isEqualTo(Option.some(of(2, 3)));
2208     }
2209 
2210     // -- unzip
2211 
2212     @Test
2213     public void shouldUnzipNil() {
2214         assertThat(empty().unzip(x -> Tuple.of(x, x))).isEqualTo(Tuple.of(empty(), empty()));
2215     }
2216 
2217     @Test
2218     public void shouldUnzipNonNil() {
2219         final Tuple actual = of(0, 1).unzip(i -> Tuple.of(i, (char) ((short) 'a' + i)));
2220         final Tuple expected = Tuple.of(of(0, 1), of('a', 'b'));
2221         assertThat(actual).isEqualTo(expected);
2222     }
2223 
2224     @Test
2225     public void shouldUnzip3Nil() {
2226         assertThat(empty().unzip3(x -> Tuple.of(x, x, x))).isEqualTo(Tuple.of(empty(), empty(), empty()));
2227     }
2228 
2229     @Test
2230     public void shouldUnzip3NonNil() {
2231         final Tuple actual = of(0, 1).unzip3(i -> Tuple.of(i, (char) ((short) 'a' + i), (char) ((short) 'a' + i + 1)));
2232         final Tuple expected = Tuple.of(of(0, 1), of('a', 'b'), of('b', 'c'));
2233         assertThat(actual).isEqualTo(expected);
2234     }
2235 
2236     // -- zip
2237 
2238     @Test
2239     public void shouldZipNils() {
2240         final Traversable<?> actual = empty().zip(empty());
2241         assertThat(actual).isEmpty();
2242     }
2243 
2244     @Test
2245     public void shouldZipEmptyAndNonNil() {
2246         final Traversable<?> actual = empty().zip(of(1));
2247         assertThat(actual).isEmpty();
2248     }
2249 
2250     @Test
2251     public void shouldZipNonEmptyAndNil() {
2252         final Traversable<?> actual = of(1).zip(empty());
2253         assertThat(actual).isEmpty();
2254     }
2255 
2256     @Test
2257     public void shouldZipNonNilsIfThisIsSmaller() {
2258         final Traversable<Tuple2<Integer, String>> actual = of(1, 2).zip(of("a", "b", "c"));
2259         @SuppressWarnings("unchecked")
2260         final Traversable<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"));
2261         assertThat(actual).isEqualTo(expected);
2262     }
2263 
2264     @Test
2265     public void shouldZipNonNilsIfThatIsSmaller() {
2266         final Traversable<Tuple2<Integer, String>> actual = of(1, 2, 3).zip(of("a", "b"));
2267         @SuppressWarnings("unchecked")
2268         final Traversable<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"));
2269         assertThat(actual).isEqualTo(expected);
2270     }
2271 
2272     @Test
2273     public void shouldZipNonNilsOfSameSize() {
2274         final Traversable<Tuple2<Integer, String>> actual = of(1, 2, 3).zip(of("a", "b", "c"));
2275         @SuppressWarnings("unchecked")
2276         final Traversable<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"), Tuple.of(3, "c"));
2277         assertThat(actual).isEqualTo(expected);
2278     }
2279 
2280     @Test
2281     @SuppressWarnings("unchecked")
2282     public void shouldZipWithNonNilsOfSameSize() {
2283         final Traversable<Tuple2<Integer, String>> actual = of(1, 2, 3).zipWith(of("a", "b", "c"), Tuple::of);
2284         final Traversable<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"), Tuple.of(3, "c"));
2285         assertThat(actual).isEqualTo(expected);
2286     }
2287 
2288     @Test(expected = NullPointerException.class)
2289     public void shouldThrowIfZipWithThatIsNull() {
2290         empty().zip(null);
2291     }
2292 
2293     // -- zipAll
2294 
2295     @Test
2296     public void shouldZipAllNils() {
2297         final Traversable<?> actual = empty().zipAll(empty(), null, null);
2298         assertThat(actual).isEmpty();
2299     }
2300 
2301     @Test
2302     public void shouldZipAllEmptyAndNonNil() {
2303         final Traversable<?> actual = empty().zipAll(of(1), null, null);
2304         final Traversable<Tuple2<Object, Integer>> expected = of(Tuple.of(null, 1));
2305         assertThat(actual).isEqualTo(expected);
2306     }
2307 
2308     @Test
2309     public void shouldZipAllNonEmptyAndNil() {
2310         final Traversable<?> actual = of(1).zipAll(empty(), null, null);
2311         final Traversable<Tuple2<Integer, Object>> expected = of(Tuple.of(1, null));
2312         assertThat(actual).isEqualTo(expected);
2313     }
2314 
2315     @Test
2316     public void shouldZipAllNonNilsIfThisIsSmaller() {
2317         final Traversable<Tuple2<Integer, String>> actual = of(1, 2).zipAll(of("a", "b", "c"), 9, "z");
2318         @SuppressWarnings("unchecked")
2319         final Traversable<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"), Tuple.of(9, "c"));
2320         assertThat(actual).isEqualTo(expected);
2321     }
2322 
2323     @Test
2324     public void shouldZipAllNonNilsIfThatIsSmaller() {
2325         final Traversable<Tuple2<Integer, String>> actual = of(1, 2, 3).zipAll(of("a", "b"), 9, "z");
2326         @SuppressWarnings("unchecked")
2327         final Traversable<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"), Tuple.of(3, "z"));
2328         assertThat(actual).isEqualTo(expected);
2329     }
2330 
2331     @Test
2332     public void shouldZipAllNonNilsOfSameSize() {
2333         final Traversable<Tuple2<Integer, String>> actual = of(1, 2, 3).zipAll(of("a", "b", "c"), 9, "z");
2334         @SuppressWarnings("unchecked")
2335         final Traversable<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"), Tuple.of(3, "c"));
2336         assertThat(actual).isEqualTo(expected);
2337     }
2338 
2339     @Test(expected = NullPointerException.class)
2340     public void shouldThrowIfZipAllWithThatIsNull() {
2341         empty().zipAll(null, null, null);
2342     }
2343 
2344     // -- zipWithIndex
2345 
2346     @Test
2347     public void shouldZipNilWithIndex() {
2348         assertThat(this.<String>empty().zipWithIndex()).isEqualTo(this.<Tuple2<String, Integer>>empty());
2349     }
2350 
2351     @Test
2352     public void shouldZipNonNilWithIndex() {
2353         final Traversable<Tuple2<String, Integer>> actual = of("a", "b", "c").zipWithIndex();
2354         @SuppressWarnings("unchecked")
2355         final Traversable<Tuple2<String, Integer>> expected = of(Tuple.of("a", 0), Tuple.of("b", 1), Tuple.of("c", 2));
2356         assertThat(actual).isEqualTo(expected);
2357     }
2358 
2359     @Test
2360     @SuppressWarnings("unchecked")
2361     public void shouldZipNonNilWithIndexWithMapper() {
2362         final Traversable<Tuple2<String, Integer>> actual = of("a", "b", "c").zipWithIndex(Tuple::of);
2363         final Traversable<Tuple2<String, Integer>> expected = of(Tuple.of("a", 0), Tuple.of("b", 1), Tuple.of("c", 2));
2364         assertThat(actual).isEqualTo(expected);
2365     }
2366 
2367     // -- toJavaArray(Class)
2368 
2369     @Test
2370     public void shouldConvertNilToJavaArray() {
2371         final Integer[] actual = List.<Integer> empty().toJavaArray(Integer.class);
2372         final Integer[] expected = new Integer[] {};
2373         assertThat(actual).isEqualTo(expected);
2374     }
2375 
2376     @Test
2377     public void shouldConvertNonNilToJavaArray() {
2378         final Integer[] array = of(1, 2).toJavaArray(Integer.class);
2379         final Integer[] expected = new Integer[] { 1, 2 };
2380         assertThat(array).isEqualTo(expected);
2381     }
2382 
2383     // -- toJavaList
2384 
2385     @Test
2386     public void shouldConvertNilToArrayList() {
2387         assertThat(this.<Integer> empty().toJavaList()).isEqualTo(new ArrayList<Integer>());
2388     }
2389 
2390     @Test
2391     public void shouldConvertNonNilToArrayList() {
2392         assertThat(of(1, 2, 3).toJavaList()).isEqualTo(asList(1, 2, 3));
2393     }
2394 
2395     // -- toJavaMap(Function)
2396 
2397     @Test
2398     public void shouldConvertNilToHashMap() {
2399         assertThat(this.<Integer> empty().toJavaMap(x -> Tuple.of(x, x))).isEqualTo(new java.util.HashMap<>());
2400     }
2401 
2402     @Test
2403     public void shouldConvertNonNilToHashMap() {
2404         final java.util.Map<Integer, Integer> expected = new java.util.HashMap<>();
2405         expected.put(1, 1);
2406         expected.put(2, 2);
2407         assertThat(of(1, 2).toJavaMap(x -> Tuple.of(x, x))).isEqualTo(expected);
2408     }
2409 
2410     // -- toJavaSet
2411 
2412     @Test
2413     public void shouldConvertNilToHashSet() {
2414         assertThat(this.<Integer> empty().toJavaSet()).isEqualTo(new java.util.HashSet<>());
2415     }
2416 
2417     @Test
2418     public void shouldConvertNonNilToHashSet() {
2419         final java.util.Set<Integer> expected = new java.util.HashSet<>();
2420         expected.add(2);
2421         expected.add(1);
2422         expected.add(3);
2423         assertThat(of(1, 2, 2, 3).toJavaSet()).isEqualTo(expected);
2424     }
2425 
2426     // ++++++ OBJECT ++++++
2427 
2428     // -- equals
2429 
2430     @SuppressWarnings("EqualsWithItself")
2431     @Test
2432     public void shouldEqualSameTraversableInstance() {
2433         final Traversable<?> nonEmpty = of(1);
2434         assertThat(nonEmpty.equals(nonEmpty)).isTrue();
2435         assertThat(empty().equals(empty())).isTrue();
2436     }
2437 
2438     @Test
2439     public void shouldNilNotEqualsNull() {
2440         assertThat(empty()).isNotNull();
2441     }
2442 
2443     @Test
2444     public void shouldNonNilNotEqualsNull() {
2445         assertThat(of(1)).isNotNull();
2446     }
2447 
2448     @Test
2449     public void shouldEmptyNotEqualsDifferentType() {
2450         assertThat(empty()).isNotEqualTo("");
2451     }
2452 
2453     @Test
2454     public void shouldNonEmptyNotEqualsDifferentType() {
2455         assertThat(of(1)).isNotEqualTo("");
2456     }
2457 
2458     @Test
2459     public void shouldRecognizeEqualityOfNils() {
2460         assertThat(empty()).isEqualTo(empty());
2461     }
2462 
2463     @Test
2464     public void shouldRecognizeEqualityOfNonNils() {
2465         assertThat(of(1, 2, 3).equals(of(1, 2, 3))).isTrue();
2466     }
2467 
2468     @Test
2469     public void shouldRecognizeNonEqualityOfTraversablesOfSameSize() {
2470         assertThat(of(1, 2, 3).equals(of(1, 2, 4))).isFalse();
2471     }
2472 
2473     @Test
2474     public void shouldRecognizeNonEqualityOfTraversablesOfDifferentSize() {
2475         assertThat(of(1, 2, 3).equals(of(1, 2))).isFalse();
2476         assertThat(of(1, 2).equals(of(1, 2, 3))).isFalse();
2477     }
2478 
2479     // -- hashCode
2480 
2481     @Test
2482     public void shouldCalculateHashCodeOfNil() {
2483         assertThat(empty().hashCode() == empty().hashCode()).isTrue();
2484     }
2485 
2486     @Test
2487     public void shouldCalculateHashCodeOfNonNil() {
2488         assertThat(of(1, 2).hashCode() == of(1, 2).hashCode()).isTrue();
2489     }
2490 
2491     @Test
2492     public void shouldCalculateDifferentHashCodesForDifferentTraversables() {
2493         assertThat(of(1, 2).hashCode() != of(2, 3).hashCode()).isTrue();
2494     }
2495 
2496     @Test
2497     public void shouldComputeHashCodeOfEmpty() {
2498         assertThat(empty().hashCode()).isEqualTo(1);
2499     }
2500 
2501     @Test
2502     public void shouldNotThrowStackOverflowErrorWhenCalculatingHashCodeOf1000000Integers() {
2503         assertThat(ofAll(io.vavr.collection.Iterator.range(0, 1000000)).hashCode()).isNotNull();
2504     }
2505 
2506     // -- toString
2507 
2508     @Test
2509     public void shouldConformEmptyStringRepresentation() {
2510         final Traversable<Object> testee = empty();
2511         if (!testee.hasDefiniteSize()) {
2512             assertThat(testee.toString()).isEqualTo(testee.stringPrefix() + "()");
2513             testee.size(); // evaluates all elements of lazy collections
2514         }
2515         assertThat(testee.toString()).isEqualTo(toString(testee));
2516     }
2517 
2518     @Test
2519     public void shouldConformNonEmptyStringRepresentation() {
2520         final Traversable<Object> testee = of("a", "b", "c");
2521         if (isTraversableAgain()) {
2522             if (!testee.hasDefiniteSize()) {
2523                 assertThat(testee.toString()).isEqualTo(testee.stringPrefix() + "(a, ?)");
2524                 testee.size(); // evaluates all elements of lazy collections
2525             }
2526             assertThat(testee.toString()).isEqualTo(toString(testee));
2527         } else {
2528             assertThat(testee.toString()).isEqualTo(testee.stringPrefix() + "(?)");
2529         }
2530     }
2531 
2532     private static String toString(Traversable<?> traversable) {
2533         return traversable.mkString(traversable.stringPrefix() + "(", ", ", ")");
2534     }
2535 
2536     // -- static collector()
2537 
2538     @Test
2539     public void shouldStreamAndCollectNil() {
2540         testCollector(() -> {
2541             final Traversable<?> actual = java.util.stream.Stream.empty().collect(collector());
2542             assertThat(actual).isEmpty();
2543         });
2544     }
2545 
2546     @Test
2547     public void shouldStreamAndCollectNonNil() {
2548         testCollector(() -> {
2549             final Traversable<?> actual = java.util.stream.Stream.of(1, 2, 3).collect(this.<Object> collector());
2550             assertThat(actual).isEqualTo(of(1, 2, 3));
2551         });
2552     }
2553 
2554     @Test
2555     public void shouldParallelStreamAndCollectNil() {
2556         testCollector(() -> {
2557             final Traversable<?> actual = java.util.stream.Stream.empty().parallel().collect(collector());
2558             assertThat(actual).isEmpty();
2559         });
2560     }
2561 
2562     @Test
2563     public void shouldParallelStreamAndCollectNonNil() {
2564         testCollector(() -> {
2565             final Traversable<?> actual = java.util.stream.Stream.of(1, 2, 3).parallel().collect(this.<Object> collector());
2566             assertThat(actual).isEqualTo(of(1, 2, 3));
2567         });
2568     }
2569 
2570     // -- single
2571 
2572     @Test(expected = NoSuchElementException.class)
2573     public void shouldSingleFailEmpty() {
2574         empty().single();
2575     }
2576 
2577     @Test(expected = NoSuchElementException.class)
2578     public void shouldSingleFailTwo() {
2579         of(1, 2).single();
2580     }
2581 
2582     @Test
2583     public void shouldSingleWork() {
2584         assertThat(of(1).single()).isEqualTo(1);
2585     }
2586 
2587     // -- singleOption
2588 
2589     @Test
2590     public void shouldSingleOptionFailEmpty() {
2591         assertThat(empty().singleOption()).isEqualTo(Option.none());
2592     }
2593 
2594     @Test
2595     public void shouldSingleOptionFailTwo() {
2596         assertThat(of(1, 2).singleOption()).isEqualTo(Option.none());
2597     }
2598 
2599     @Test
2600     public void shouldSingleOptionWork() {
2601         assertThat(of(1).singleOption()).isEqualTo(Option.of(1));
2602     }
2603 
2604     @Test
2605     public void shouldTabulateTheSeq() {
2606         final Function<Number, Integer> f = i -> i.intValue() * i.intValue();
2607         final Traversable<Number> actual = tabulate(3, f);
2608         assertThat(actual).isEqualTo(of(0, 1, 4));
2609     }
2610 
2611     @Test
2612     public void shouldTabulateTheSeqCallingTheFunctionInTheRightOrder() {
2613         final java.util.LinkedList<Integer> ints = new java.util.LinkedList<>(asList(0, 1, 2));
2614         final Function<Integer, Integer> f = i -> ints.remove();
2615         final Traversable<Integer> actual = tabulate(3, f);
2616         assertThat(actual).isEqualTo(of(0, 1, 2));
2617     }
2618 
2619     @Test
2620     public void shouldTabulateTheSeqWith0Elements() {
2621         assertThat(tabulate(0, i -> i)).isEqualTo(empty());
2622     }
2623 
2624     @Test
2625     public void shouldTabulateTheSeqWith0ElementsWhenNIsNegative() {
2626         assertThat(tabulate(-1, i -> i)).isEqualTo(empty());
2627     }
2628 
2629     @Test
2630     public void shouldFillTheSeqCallingTheSupplierInTheRightOrder() {
2631         final java.util.LinkedList<Integer> ints = new java.util.LinkedList<>(asList(0, 1));
2632         final Traversable<Number> actual = fill(2, ints::remove);
2633         assertThat(actual).isEqualTo(of(0, 1));
2634     }
2635 
2636     @Test
2637     public void shouldFillTheSeqWith0Elements() {
2638         assertThat(fill(0, () -> 1)).isEqualTo(empty());
2639     }
2640 
2641     @Test
2642     public void shouldFillTheSeqWith0ElementsWhenNIsNegative() {
2643         assertThat(fill(-1, () -> 1)).isEqualTo(empty());
2644     }
2645 
2646     @Test
2647     public void ofShouldReturnTheSingletonEmpty() {
2648         if (!emptyShouldBeSingleton()) { return; }
2649         assertThat(of()).isSameAs(empty());
2650     }
2651 
2652     @Test
2653     public void ofAllShouldReturnTheSingletonEmpty() {
2654         if (!emptyShouldBeSingleton()) { return; }
2655         assertThat(ofAll(io.vavr.collection.Iterator.empty())).isSameAs(empty());
2656     }
2657 
2658     private void testCollector(Runnable test) {
2659         if (isTraversableAgain()) {
2660             test.run();
2661         } else {
2662             try {
2663                 collector();
2664                 fail("Collections which are not traversable again should not define a Collector.");
2665             } catch (UnsupportedOperationException x) {
2666                 // ok
2667             } catch (Throwable x) {
2668                 fail("Unexpected exception", x);
2669             }
2670         }
2671     }
2672 
2673     // helpers
2674 
2675     private static PrintStream failingPrintStream() {
2676         return new PrintStream(new OutputStream() {
2677             @Override
2678             public void write(int b) throws IOException {
2679                 throw new IOException();
2680             }
2681         });
2682     }
2683 
2684     private static PrintWriter failingPrintWriter() {
2685         return new PrintWriter(new OutputStream() {
2686             @Override
2687             public void write(int b) throws IOException {
2688                 throw new IOException();
2689             }
2690         });
2691     }
2692 
2693     /**
2694      * Wraps a String in order to ensure that it is not Comparable.
2695      */
2696     static final class NonComparable {
2697 
2698         final String value;
2699 
2700         NonComparable(String value) {
2701             this.value = value;
2702         }
2703 
2704         @Override
2705         public int hashCode() {
2706             return Objects.hash(value);
2707         }
2708 
2709         @Override
2710         public boolean equals(Object obj) {
2711             if (obj == this) {
2712                 return true;
2713             } else if (obj instanceof NonComparable) {
2714                 final NonComparable that = (NonComparable) obj;
2715                 return Objects.equals(this.value, that.value);
2716             } else {
2717                 return false;
2718             }
2719         }
2720 
2721         @Override
2722         public String toString() {
2723             return value;
2724         }
2725     }
2726 }